From 48b68af5879a838dea43e1d0ab4f83b5eae64a58 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Mon, 28 Apr 2025 16:49:39 -0400 Subject: [PATCH] From https://www.jwz.org/xscreensaver/xscreensaver-6.10.1.tar.gz -rw-rw-r-- 1 zblaxell zblaxell 25081752 Apr 28 16:08 xscreensaver-6.10.1.tar.gz 05a7e1dab3bb0a1e663c9037baf79f84ac7ee498 xscreensaver-6.10.1.tar.gz --- Makefile.in | 9 +- OSX/README | 4 +- OSX/Randomizer.plist | 10 +- OSX/SaverRunner.m | 1 + OSX/SaverRunner.plist | 10 +- OSX/Updater.plist | 10 +- OSX/XScreenSaver.plist | 10 +- OSX/bindist.rtf | 17 +- OSX/bindist2.webloc | 2 +- OSX/iSaverRunner.plist | 10 +- OSX/installer.rtf | 6 +- OSX/ios-function-table.m | 10 +- OSX/perl-minimize.pl | 139 + OSX/tvSaverRunner.plist | 10 +- OSX/update-info-plist.pl | 33 +- OSX/updates.xml | 22 +- OSX/xscreensaver.xcodeproj/project.pbxproj | 644 +- .../xcschemes/Abstractile.xcscheme | 2 +- .../xcschemes/All Savers (OpenGL).xcscheme | 2 +- .../xcschemes/All Savers (XLockmore).xcscheme | 2 +- .../All Savers (XScreenSaver).xcscheme | 2 +- .../xcschemes/All Savers.xcscheme | 2 +- .../xcshareddata/xcschemes/Anemone.xcscheme | 2 +- .../xcschemes/Anemotaxis.xcscheme | 2 +- .../xcshareddata/xcschemes/Ant.xcscheme | 2 +- .../xcschemes/AntInspect.xcscheme | 2 +- .../xcshareddata/xcschemes/AntMaze.xcscheme | 2 +- .../xcschemes/AntSpotlight.xcscheme | 2 +- .../xcschemes/Apollonian.xcscheme | 2 +- .../xcschemes/Apple2-OSX.xcscheme | 2 +- .../xcschemes/Apple2-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/Apple2.xcscheme | 2 +- .../xcshareddata/xcschemes/Atlantis.xcscheme | 2 +- .../xcschemes/Attraction.xcscheme | 2 +- .../xcshareddata/xcschemes/Atunnel.xcscheme | 2 +- .../xcshareddata/xcschemes/BSOD.xcscheme | 2 +- .../xcshareddata/xcschemes/Barcode.xcscheme | 2 +- .../xcshareddata/xcschemes/Beats.xcscheme | 2 +- .../xcschemes/BinaryHorizon.xcscheme | 2 +- .../xcschemes/BinaryRing.xcscheme | 2 +- .../xcshareddata/xcschemes/Blaster.xcscheme | 2 +- .../xcshareddata/xcschemes/BlinkBox.xcscheme | 2 +- .../xcshareddata/xcschemes/BlitSpin.xcscheme | 2 +- .../xcshareddata/xcschemes/BlockTube.xcscheme | 2 +- .../xcshareddata/xcschemes/Boing.xcscheme | 2 +- .../xcshareddata/xcschemes/Bouboule.xcscheme | 2 +- .../xcschemes/BouncingCow.xcscheme | 2 +- .../xcshareddata/xcschemes/BoxFit.xcscheme | 2 +- .../xcshareddata/xcschemes/Boxed.xcscheme | 2 +- .../xcshareddata/xcschemes/Braid.xcscheme | 2 +- .../xcshareddata/xcschemes/Bubble3D.xcscheme | 2 +- .../xcshareddata/xcschemes/Bubbles.xcscheme | 2 +- .../xcshareddata/xcschemes/Bumps.xcscheme | 2 +- .../xcshareddata/xcschemes/CCurve.xcscheme | 2 +- .../xcshareddata/xcschemes/COVID19.xcscheme | 2 +- .../xcshareddata/xcschemes/CWaves.xcscheme | 2 +- .../xcshareddata/xcschemes/Cage.xcscheme | 2 +- .../xcshareddata/xcschemes/Carousel.xcscheme | 2 +- .../xcshareddata/xcschemes/Celtic.xcscheme | 2 +- .../xcschemes/ChompyTower.xcscheme | 2 +- .../xcshareddata/xcschemes/Circuit.xcscheme | 2 +- .../xcshareddata/xcschemes/Cityflow.xcscheme | 2 +- .../xcshareddata/xcschemes/CloudLife.xcscheme | 2 +- .../xcschemes/CompanionCube.xcscheme | 2 +- .../xcshareddata/xcschemes/Compass.xcscheme | 2 +- .../xcshareddata/xcschemes/Coral.xcscheme | 2 +- .../xcshareddata/xcschemes/Crackberg.xcscheme | 2 +- .../xcshareddata/xcschemes/Critical.xcscheme | 2 +- .../xcshareddata/xcschemes/Crumbler.xcscheme | 2 +- .../xcshareddata/xcschemes/Crystal.xcscheme | 2 +- .../xcshareddata/xcschemes/Cube21.xcscheme | 2 +- .../xcshareddata/xcschemes/CubeStack.xcscheme | 2 +- .../xcshareddata/xcschemes/CubeStorm.xcscheme | 2 +- .../xcshareddata/xcschemes/CubeTwist.xcscheme | 2 +- .../xcshareddata/xcschemes/Cubenetic.xcscheme | 2 +- .../xcshareddata/xcschemes/CubicGrid.xcscheme | 2 +- .../xcschemes/CuboctEversion.xcscheme | 2 +- .../xcshareddata/xcschemes/Cynosure.xcscheme | 2 +- .../xcshareddata/xcschemes/DNAlogo.xcscheme | 2 +- .../xcschemes/DangerBall.xcscheme | 2 +- .../xcschemes/DecayScreen.xcscheme | 2 +- .../xcshareddata/xcschemes/Deco.xcscheme | 2 +- .../xcshareddata/xcschemes/DeepStars.xcscheme | 2 +- .../xcshareddata/xcschemes/Deluxe.xcscheme | 2 +- .../xcshareddata/xcschemes/Demon.xcscheme | 2 +- .../xcshareddata/xcschemes/Discoball.xcscheme | 2 +- .../xcshareddata/xcschemes/Discrete.xcscheme | 2 +- .../xcshareddata/xcschemes/Distort.xcscheme | 2 +- .../xcshareddata/xcschemes/Drift.xcscheme | 2 +- .../xcshareddata/xcschemes/Droste.xcscheme | 2 +- .../xcschemes/DumpsterFire.xcscheme | 85 + .../xcschemes/DymaxionMap.xcscheme | 2 +- .../xcshareddata/xcschemes/Endgame.xcscheme | 2 +- .../xcschemes/EnergyStream.xcscheme | 2 +- .../xcshareddata/xcschemes/Engine.xcscheme | 2 +- .../xcshareddata/xcschemes/Epicycle.xcscheme | 2 +- .../xcshareddata/xcschemes/Eruption.xcscheme | 2 +- .../xcshareddata/xcschemes/Esper.xcscheme | 2 +- .../xcschemes/EtruscanVenus.xcscheme | 2 +- .../xcshareddata/xcschemes/Euler2D.xcscheme | 2 +- .../xcshareddata/xcschemes/Extrusion.xcscheme | 2 +- .../xcshareddata/xcschemes/FadePlot.xcscheme | 2 +- .../xcshareddata/xcschemes/Fiberlamp.xcscheme | 2 +- .../xcschemes/FilmLeader.xcscheme | 2 +- .../xcshareddata/xcschemes/Fireworkx.xcscheme | 2 +- .../xcshareddata/xcschemes/Flag.xcscheme | 2 +- .../xcshareddata/xcschemes/Flame.xcscheme | 2 +- .../xcshareddata/xcschemes/FlipFlop.xcscheme | 2 +- .../xcschemes/FlipScreen3D.xcscheme | 2 +- .../xcshareddata/xcschemes/FlipText.xcscheme | 2 +- .../xcshareddata/xcschemes/Flow.xcscheme | 2 +- .../xcschemes/FluidBalls.xcscheme | 2 +- .../xcschemes/FlyingToasters.xcscheme | 2 +- .../xcshareddata/xcschemes/FontGlide.xcscheme | 2 +- .../xcshareddata/xcschemes/Forest.xcscheme | 2 +- .../xcschemes/FuzzyFlakes.xcscheme | 2 +- .../xcshareddata/xcschemes/GFlux.xcscheme | 2 +- .../xcshareddata/xcschemes/GLBlur.xcscheme | 2 +- .../xcshareddata/xcschemes/GLCells.xcscheme | 2 +- .../xcschemes/GLForestFire.xcscheme | 2 +- .../xcshareddata/xcschemes/GLHanoi.xcscheme | 2 +- .../xcshareddata/xcschemes/GLKnots.xcscheme | 2 +- .../xcshareddata/xcschemes/GLMatrix.xcscheme | 2 +- .../xcshareddata/xcschemes/GLPlanet.xcscheme | 2 +- .../xcshareddata/xcschemes/GLSchool.xcscheme | 2 +- .../xcschemes/GLSlideshow.xcscheme | 2 +- .../xcshareddata/xcschemes/GLSnake.xcscheme | 2 +- .../xcshareddata/xcschemes/GLText.xcscheme | 2 +- .../xcshareddata/xcschemes/Galaxy.xcscheme | 2 +- .../xcshareddata/xcschemes/Gears.xcscheme | 2 +- .../xcshareddata/xcschemes/Geodesic.xcscheme | 2 +- .../xcschemes/GeodesicGears.xcscheme | 2 +- .../xcshareddata/xcschemes/Gibson.xcscheme | 2 +- .../xcschemes/Gleidescope.xcscheme | 2 +- .../xcshareddata/xcschemes/GlitchPEG.xcscheme | 2 +- .../xcshareddata/xcschemes/Goop.xcscheme | 2 +- .../xcshareddata/xcschemes/Grav.xcscheme | 2 +- .../xcschemes/GravityWell.xcscheme | 2 +- .../xcshareddata/xcschemes/Greynetic.xcscheme | 2 +- .../xcshareddata/xcschemes/Halftone.xcscheme | 2 +- .../xcshareddata/xcschemes/Halo.xcscheme | 2 +- .../xcshareddata/xcschemes/Handsy.xcscheme | 2 +- .../xcshareddata/xcschemes/Headroom.xcscheme | 2 +- .../xcshareddata/xcschemes/Helix.xcscheme | 2 +- .../xcshareddata/xcschemes/HexTrail.xcscheme | 2 +- .../xcshareddata/xcschemes/Hexadrop.xcscheme | 2 +- .../xcshareddata/xcschemes/Hexstrut.xcscheme | 2 +- .../xcschemes/HighVoltage.xcscheme | 2 +- .../xcshareddata/xcschemes/Hilbert.xcscheme | 2 +- .../xcshareddata/xcschemes/Hopalong.xcscheme | 2 +- .../xcschemes/HopfFibration.xcscheme | 85 + .../xcshareddata/xcschemes/Hydrostat.xcscheme | 2 +- .../xcshareddata/xcschemes/HyperBall.xcscheme | 2 +- .../xcshareddata/xcschemes/HyperCube.xcscheme | 2 +- .../xcschemes/Hypertorus.xcscheme | 2 +- .../xcschemes/Hypnowheel.xcscheme | 2 +- .../xcshareddata/xcschemes/IFS.xcscheme | 2 +- .../xcshareddata/xcschemes/IMSMap.xcscheme | 2 +- .../xcschemes/Interaggregate.xcscheme | 2 +- .../xcschemes/Interference.xcscheme | 2 +- .../xcschemes/Intermomentary.xcscheme | 2 +- .../xcschemes/JigglyPuff.xcscheme | 2 +- .../xcshareddata/xcschemes/Jigsaw.xcscheme | 2 +- .../xcshareddata/xcschemes/Juggle.xcscheme | 2 +- .../xcshareddata/xcschemes/Juggler3D.xcscheme | 2 +- .../xcshareddata/xcschemes/Julia.xcscheme | 2 +- .../xcschemes/Kaleidescope.xcscheme | 2 +- .../xcschemes/Kaleidocycle.xcscheme | 2 +- .../xcshareddata/xcschemes/Kallisti.xcscheme | 2 +- .../xcshareddata/xcschemes/Klein.xcscheme | 2 +- .../xcshareddata/xcschemes/Klondike.xcscheme | 85 + .../xcshareddata/xcschemes/Kumppa.xcscheme | 2 +- .../xcshareddata/xcschemes/LCDscrub.xcscheme | 2 +- .../xcshareddata/xcschemes/LMorph.xcscheme | 2 +- .../xcshareddata/xcschemes/Lament.xcscheme | 2 +- .../xcshareddata/xcschemes/Laser.xcscheme | 2 +- .../xcshareddata/xcschemes/Lavalite.xcscheme | 2 +- .../xcshareddata/xcschemes/Lightning.xcscheme | 2 +- .../xcshareddata/xcschemes/Lisa.xcscheme | 2 +- .../xcshareddata/xcschemes/Lissie.xcscheme | 2 +- .../xcshareddata/xcschemes/Lockward.xcscheme | 2 +- .../xcshareddata/xcschemes/Loop.xcscheme | 2 +- .../xcschemes/MapScroller.xcscheme | 2 +- .../xcshareddata/xcschemes/Marbling.xcscheme | 2 +- .../xcshareddata/xcschemes/Maze.xcscheme | 2 +- .../xcshareddata/xcschemes/Maze3D.xcscheme | 2 +- .../xcschemes/MemScroller.xcscheme | 2 +- .../xcshareddata/xcschemes/Menger.xcscheme | 2 +- .../xcshareddata/xcschemes/MetaBalls.xcscheme | 2 +- .../xcschemes/MirrorBlob.xcscheme | 2 +- .../xcshareddata/xcschemes/Moebius.xcscheme | 2 +- .../xcschemes/MoebiusGears.xcscheme | 2 +- .../xcshareddata/xcschemes/Moire.xcscheme | 2 +- .../xcshareddata/xcschemes/Moire2.xcscheme | 2 +- .../xcshareddata/xcschemes/Molecule.xcscheme | 2 +- .../xcshareddata/xcschemes/Morph3D.xcscheme | 2 +- .../xcshareddata/xcschemes/Mountain.xcscheme | 2 +- .../xcshareddata/xcschemes/Munch.xcscheme | 2 +- .../xcshareddata/xcschemes/Nakagin.xcscheme | 2 +- .../xcshareddata/xcschemes/NerveRot.xcscheme | 2 +- .../xcshareddata/xcschemes/Noof.xcscheme | 2 +- .../xcshareddata/xcschemes/NoseGuy.xcscheme | 2 +- .../xcshareddata/xcschemes/Obsolete.xcscheme | 2 +- .../xcshareddata/xcschemes/Pacman.xcscheme | 2 +- .../xcshareddata/xcschemes/PaperCube.xcscheme | 2 +- .../xcshareddata/xcschemes/Pedal.xcscheme | 2 +- .../xcshareddata/xcschemes/Peepers.xcscheme | 2 +- .../xcshareddata/xcschemes/Penetrate.xcscheme | 2 +- .../xcshareddata/xcschemes/Penrose.xcscheme | 2 +- .../xcshareddata/xcschemes/Petri.xcscheme | 2 +- .../xcschemes/Phosphor-OSX.xcscheme | 2 +- .../xcschemes/Phosphor-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/Phosphor.xcscheme | 2 +- .../xcshareddata/xcschemes/Photopile.xcscheme | 2 +- .../xcshareddata/xcschemes/Piecewise.xcscheme | 2 +- .../xcshareddata/xcschemes/Pinion.xcscheme | 2 +- .../xcshareddata/xcschemes/Pipes.xcscheme | 2 +- .../xcschemes/PlatonicFolding.xcscheme | 85 + .../xcshareddata/xcschemes/Polyhedra.xcscheme | 2 +- .../xcschemes/Polyominoes.xcscheme | 2 +- .../xcshareddata/xcschemes/Polytopes.xcscheme | 2 +- .../xcshareddata/xcschemes/Pong.xcscheme | 2 +- .../xcschemes/PopSquares.xcscheme | 2 +- .../xcschemes/ProjectivePlane.xcscheme | 2 +- .../xcschemes/Providence.xcscheme | 2 +- .../xcshareddata/xcschemes/Pulsar.xcscheme | 2 +- .../xcshareddata/xcschemes/Pyro.xcscheme | 2 +- .../xcshareddata/xcschemes/Qix.xcscheme | 2 +- .../xcschemes/QuasiCrystal.xcscheme | 2 +- .../xcshareddata/xcschemes/Queens.xcscheme | 2 +- .../xcshareddata/xcschemes/RDbomb.xcscheme | 2 +- .../xcschemes/RandomXScreenSaver.xcscheme | 2 +- .../xcshareddata/xcschemes/RaverHoop.xcscheme | 2 +- .../xcschemes/RazzleDazzle.xcscheme | 2 +- .../xcshareddata/xcschemes/Ripples.xcscheme | 2 +- .../xcshareddata/xcschemes/Rocks.xcscheme | 2 +- .../xcshareddata/xcschemes/RomanBoy.xcscheme | 2 +- .../xcshareddata/xcschemes/Rorschach.xcscheme | 2 +- .../xcshareddata/xcschemes/RotZoomer.xcscheme | 2 +- .../xcshareddata/xcschemes/Rotor.xcscheme | 2 +- .../xcshareddata/xcschemes/Rubik.xcscheme | 2 +- .../xcschemes/RubikBlocks.xcscheme | 2 +- .../xcshareddata/xcschemes/SBalls.xcscheme | 2 +- .../xcschemes/SaverTester.xcscheme | 4 +- .../xcshareddata/xcschemes/Scooter.xcscheme | 2 +- .../xcshareddata/xcschemes/ShadeBobs.xcscheme | 2 +- .../xcschemes/Sierpinski.xcscheme | 2 +- .../xcschemes/Sierpinski3D.xcscheme | 2 +- .../xcshareddata/xcschemes/Skulloop.xcscheme | 2 +- .../xcschemes/SkyTentacles.xcscheme | 2 +- .../xcschemes/SlideScreen.xcscheme | 2 +- .../xcshareddata/xcschemes/Slip.xcscheme | 2 +- .../xcshareddata/xcschemes/Sonar.xcscheme | 2 +- .../xcshareddata/xcschemes/SpeedMine.xcscheme | 2 +- .../xcshareddata/xcschemes/Sphere.xcscheme | 2 +- .../xcschemes/SphereEversion.xcscheme | 2 +- .../xcschemes/Spheremonics.xcscheme | 2 +- .../xcshareddata/xcschemes/Spiral.xcscheme | 2 +- .../xcshareddata/xcschemes/SplitFlap.xcscheme | 2 +- .../xcshareddata/xcschemes/Splodesic.xcscheme | 2 +- .../xcshareddata/xcschemes/Spotlight.xcscheme | 2 +- .../xcschemes/Sproingies.xcscheme | 2 +- .../xcshareddata/xcschemes/Squiral.xcscheme | 2 +- .../xcschemes/Squirtorus.xcscheme | 2 +- .../xcshareddata/xcschemes/Stairs.xcscheme | 2 +- .../xcshareddata/xcschemes/StarWars.xcscheme | 2 +- .../xcshareddata/xcschemes/Starfish.xcscheme | 2 +- .../xcschemes/StonerView.xcscheme | 2 +- .../xcshareddata/xcschemes/Strange.xcscheme | 2 +- .../xcshareddata/xcschemes/Substrate.xcscheme | 2 +- .../xcschemes/Superquadrics.xcscheme | 2 +- .../xcshareddata/xcschemes/Surfaces.xcscheme | 2 +- .../xcshareddata/xcschemes/Swirl.xcscheme | 2 +- .../xcshareddata/xcschemes/T3D.xcscheme | 2 +- .../xcshareddata/xcschemes/Tangram.xcscheme | 2 +- .../xcschemes/Tessellimage.xcscheme | 2 +- .../xcschemes/TestX11-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/TestX11.xcscheme | 2 +- .../xcshareddata/xcschemes/Thornbird.xcscheme | 2 +- .../xcschemes/TimeTunnel.xcscheme | 2 +- .../xcshareddata/xcschemes/TopBlock.xcscheme | 2 +- .../xcshareddata/xcschemes/Triangle.xcscheme | 2 +- .../xcshareddata/xcschemes/TronBit.xcscheme | 2 +- .../xcshareddata/xcschemes/Truchet.xcscheme | 2 +- .../xcshareddata/xcschemes/Twang.xcscheme | 2 +- .../xcshareddata/xcschemes/Unicrud.xcscheme | 2 +- .../xcschemes/UnknownPleasures.xcscheme | 2 +- .../xcshareddata/xcschemes/VFeedback.xcscheme | 2 +- .../xcschemes/Vermiculate.xcscheme | 2 +- .../xcshareddata/xcschemes/Vigilance.xcscheme | 2 +- .../xcshareddata/xcschemes/Vines.xcscheme | 2 +- .../xcshareddata/xcschemes/Voronoi.xcscheme | 2 +- .../xcshareddata/xcschemes/Wander.xcscheme | 2 +- .../xcschemes/WebCollage.xcscheme | 2 +- .../xcschemes/WhirlWindWarp.xcscheme | 2 +- .../xcshareddata/xcschemes/Whirlygig.xcscheme | 2 +- .../xcschemes/WindupRobot.xcscheme | 2 +- .../xcshareddata/xcschemes/Worm.xcscheme | 2 +- .../xcshareddata/xcschemes/Wormhole.xcscheme | 2 +- .../xcshareddata/xcschemes/XAnalogTV.xcscheme | 2 +- .../xcshareddata/xcschemes/XFlame.xcscheme | 2 +- .../xcshareddata/xcschemes/XJack.xcscheme | 2 +- .../xcshareddata/xcschemes/XLyap.xcscheme | 2 +- .../xcshareddata/xcschemes/XMatrix.xcscheme | 2 +- .../xcshareddata/xcschemes/XRaySwarm.xcscheme | 2 +- .../xcschemes/XScreenSaver-iOS.xcscheme | 2 +- .../xcschemes/XScreenSaver-tvOS.xcscheme | 2 +- .../xcschemes/XScreenSaverUpdater.xcscheme | 2 +- .../xcschemes/XSpirograph.xcscheme | 2 +- .../xcshareddata/xcschemes/Zoom.xcscheme | 2 +- .../xcshareddata/xcschemes/enable_gc.xcscheme | 2 +- .../xcschemes/images_png_h.xcscheme | 2 +- .../xcshareddata/xcschemes/jwxyz.xcscheme | 2 +- .../xcshareddata/xcschemes/m6502.h.xcscheme | 2 +- .../xcshareddata/xcschemes/m6502.xcscheme | 2 +- .../xcschemes/molecules.h.xcscheme | 2 +- README | 10 +- aclocal.m4 | 6 +- android/Makefile | 4 + android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 3 +- android/xscreensaver/build.gradle | 4 +- android/xscreensaver/jni/Android.mk | 5 + .../src/org/jwz/xscreensaver/Activity.java | 9 +- .../src/org/jwz/xscreensaver/jwxyz.java | 12 +- configure | 79 +- configure.ac | 25 +- driver/XScreenSaver.ad.in | 13 +- driver/XScreenSaver_ad.h | 9 +- driver/auth.h | 3 +- driver/dialog.c | 15 + driver/test-passwd.c | 5 +- driver/xscreensaver-settings.man | 8 +- driver/xscreensaver-systemd.c | 32 +- hacks/Makefile.in | 93 +- hacks/analogtv-cli.c | 27 +- hacks/ansi-tty.c | 1930 ++ hacks/ansi-tty.h | 63 + hacks/apple2-main.c | 574 +- hacks/barcode.c | 17 + hacks/bsod.c | 458 +- hacks/check-configs.pl | 32 +- hacks/config/README | 4 +- hacks/config/bsod.xml | 4 +- hacks/config/dumpsterfire.xml | 39 + hacks/config/hopffibration.xml | 82 + hacks/config/klondike.xml | 50 + hacks/config/platonicfolding.xml | 74 + hacks/config/sonar.xml | 5 +- hacks/ffmpeg-out.c | 124 +- hacks/glx/Makefile.in | 192 +- hacks/glx/cubocteversion.c | 20 +- hacks/glx/dumpster.dxf | 16278 ++++++++++++++++ hacks/glx/dumpster_model.c | 1667 ++ hacks/glx/dumpsterfire.c | 860 + hacks/glx/flyingtoasters.c | 2 +- hacks/glx/fps-gl.c | 7 +- hacks/glx/glsl-utils.c | 166 +- hacks/glx/glsl-utils.h | 15 +- hacks/glx/glsnake.c | 12 + hacks/glx/gltrackball.c | 9 +- hacks/glx/hopfanimations.c | 10224 ++++++++++ hacks/glx/hopfanimations.h | 123 + hacks/glx/hopffibration.c | 3647 ++++ hacks/glx/hopffibration.man | 285 + hacks/glx/klondike-game.c | 814 + hacks/glx/klondike-game.h | 107 + hacks/glx/klondike.c | 809 + hacks/glx/platonicfolding.c | 3522 ++++ hacks/glx/platonicfolding.man | 165 + hacks/glx/polyhedra.c | 2 +- hacks/glx/sonar-icmp.c | 71 +- hacks/glx/xlock-gl-utils.c | 14 +- hacks/images/klondike/C2.png | Bin 0 -> 11047 bytes hacks/images/klondike/C3.png | Bin 0 -> 12563 bytes hacks/images/klondike/C4.png | Bin 0 -> 11157 bytes hacks/images/klondike/C5.png | Bin 0 -> 12717 bytes hacks/images/klondike/C6.png | Bin 0 -> 13197 bytes hacks/images/klondike/C7.png | Bin 0 -> 14270 bytes hacks/images/klondike/C8.png | Bin 0 -> 16234 bytes hacks/images/klondike/C9.png | Bin 0 -> 16333 bytes hacks/images/klondike/CA.png | Bin 0 -> 9648 bytes hacks/images/klondike/CJ.png | Bin 0 -> 176711 bytes hacks/images/klondike/CK.png | Bin 0 -> 161025 bytes hacks/images/klondike/CQ.png | Bin 0 -> 179705 bytes hacks/images/klondike/CT.png | Bin 0 -> 17616 bytes hacks/images/klondike/D2.png | Bin 0 -> 13905 bytes hacks/images/klondike/D3.png | Bin 0 -> 15544 bytes hacks/images/klondike/D4.png | Bin 0 -> 13889 bytes hacks/images/klondike/D5.png | Bin 0 -> 15920 bytes hacks/images/klondike/D6.png | Bin 0 -> 15908 bytes hacks/images/klondike/D7.png | Bin 0 -> 17220 bytes hacks/images/klondike/D8.png | Bin 0 -> 19440 bytes hacks/images/klondike/D9.png | Bin 0 -> 19162 bytes hacks/images/klondike/DA.png | Bin 0 -> 12486 bytes hacks/images/klondike/DJ.png | Bin 0 -> 161282 bytes hacks/images/klondike/DK.png | Bin 0 -> 170908 bytes hacks/images/klondike/DQ.png | Bin 0 -> 162304 bytes hacks/images/klondike/DT.png | Bin 0 -> 20963 bytes hacks/images/klondike/H2.png | Bin 0 -> 14426 bytes hacks/images/klondike/H3.png | Bin 0 -> 16377 bytes hacks/images/klondike/H4.png | Bin 0 -> 14475 bytes hacks/images/klondike/H5.png | Bin 0 -> 16301 bytes hacks/images/klondike/H6.png | Bin 0 -> 16849 bytes hacks/images/klondike/H7.png | Bin 0 -> 18258 bytes hacks/images/klondike/H8.png | Bin 0 -> 20756 bytes hacks/images/klondike/H9.png | Bin 0 -> 20492 bytes hacks/images/klondike/HA.png | Bin 0 -> 12993 bytes hacks/images/klondike/HJ.png | Bin 0 -> 188326 bytes hacks/images/klondike/HK.png | Bin 0 -> 182952 bytes hacks/images/klondike/HQ.png | Bin 0 -> 177564 bytes hacks/images/klondike/HT.png | Bin 0 -> 22379 bytes hacks/images/klondike/S2.png | Bin 0 -> 10650 bytes hacks/images/klondike/S3.png | Bin 0 -> 12041 bytes hacks/images/klondike/S4.png | Bin 0 -> 10800 bytes hacks/images/klondike/S5.png | Bin 0 -> 12134 bytes hacks/images/klondike/S6.png | Bin 0 -> 12522 bytes hacks/images/klondike/S7.png | Bin 0 -> 13584 bytes hacks/images/klondike/S8.png | Bin 0 -> 15308 bytes hacks/images/klondike/S9.png | Bin 0 -> 15221 bytes hacks/images/klondike/SA.png | Bin 0 -> 9382 bytes hacks/images/klondike/SJ.png | Bin 0 -> 165145 bytes hacks/images/klondike/SK.png | Bin 0 -> 165617 bytes hacks/images/klondike/SQ.png | Bin 0 -> 177476 bytes hacks/images/klondike/ST.png | Bin 0 -> 16632 bytes hacks/images/klondike/attribution.txt | 18 + hacks/images/klondike/back.png | Bin 0 -> 155518 bytes hacks/images/klondike/back0.png | Bin 0 -> 161838 bytes hacks/phosphor.c | 1131 +- hacks/phosphor.man | 6 +- hacks/screenhack.c | 47 +- hacks/screenhackI.h | 4 +- hacks/webcollage | 145 +- hacks/xscreensaver-text | 25 +- jwxyz/jwxyz.h | 36 +- jwxyz/jwzgles.c | 18 + jwxyz/jwzglesI.h | 10 + po/POTFILES.in | 6 +- utils/bin2c | 8 +- utils/textclient-mobile.c | 10 +- utils/textclient.c | 153 +- utils/textclient.h | 5 +- utils/version.h | 6 +- utils/visual-gl.c | 20 +- utils/xft.c | 12 +- utils/xft.h | 3 +- utils/xftwrap.c | 18 +- xscreensaver.spec | 4 +- 448 files changed, 44558 insertions(+), 1837 deletions(-) create mode 100755 OSX/perl-minimize.pl create mode 100644 OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/DumpsterFire.xcscheme create mode 100644 OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/HopfFibration.xcscheme create mode 100644 OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Klondike.xcscheme create mode 100644 OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/PlatonicFolding.xcscheme create mode 100644 hacks/ansi-tty.c create mode 100644 hacks/ansi-tty.h create mode 100644 hacks/config/dumpsterfire.xml create mode 100644 hacks/config/hopffibration.xml create mode 100644 hacks/config/klondike.xml create mode 100644 hacks/config/platonicfolding.xml create mode 100644 hacks/glx/dumpster.dxf create mode 100644 hacks/glx/dumpster_model.c create mode 100644 hacks/glx/dumpsterfire.c create mode 100644 hacks/glx/hopfanimations.c create mode 100644 hacks/glx/hopfanimations.h create mode 100644 hacks/glx/hopffibration.c create mode 100644 hacks/glx/hopffibration.man create mode 100644 hacks/glx/klondike-game.c create mode 100644 hacks/glx/klondike-game.h create mode 100644 hacks/glx/klondike.c create mode 100644 hacks/glx/platonicfolding.c create mode 100644 hacks/glx/platonicfolding.man create mode 100644 hacks/images/klondike/C2.png create mode 100644 hacks/images/klondike/C3.png create mode 100644 hacks/images/klondike/C4.png create mode 100644 hacks/images/klondike/C5.png create mode 100644 hacks/images/klondike/C6.png create mode 100644 hacks/images/klondike/C7.png create mode 100644 hacks/images/klondike/C8.png create mode 100644 hacks/images/klondike/C9.png create mode 100644 hacks/images/klondike/CA.png create mode 100644 hacks/images/klondike/CJ.png create mode 100644 hacks/images/klondike/CK.png create mode 100644 hacks/images/klondike/CQ.png create mode 100644 hacks/images/klondike/CT.png create mode 100644 hacks/images/klondike/D2.png create mode 100644 hacks/images/klondike/D3.png create mode 100644 hacks/images/klondike/D4.png create mode 100644 hacks/images/klondike/D5.png create mode 100644 hacks/images/klondike/D6.png create mode 100644 hacks/images/klondike/D7.png create mode 100644 hacks/images/klondike/D8.png create mode 100644 hacks/images/klondike/D9.png create mode 100644 hacks/images/klondike/DA.png create mode 100644 hacks/images/klondike/DJ.png create mode 100644 hacks/images/klondike/DK.png create mode 100644 hacks/images/klondike/DQ.png create mode 100644 hacks/images/klondike/DT.png create mode 100644 hacks/images/klondike/H2.png create mode 100644 hacks/images/klondike/H3.png create mode 100644 hacks/images/klondike/H4.png create mode 100644 hacks/images/klondike/H5.png create mode 100644 hacks/images/klondike/H6.png create mode 100644 hacks/images/klondike/H7.png create mode 100644 hacks/images/klondike/H8.png create mode 100644 hacks/images/klondike/H9.png create mode 100644 hacks/images/klondike/HA.png create mode 100644 hacks/images/klondike/HJ.png create mode 100644 hacks/images/klondike/HK.png create mode 100644 hacks/images/klondike/HQ.png create mode 100644 hacks/images/klondike/HT.png create mode 100644 hacks/images/klondike/S2.png create mode 100644 hacks/images/klondike/S3.png create mode 100644 hacks/images/klondike/S4.png create mode 100644 hacks/images/klondike/S5.png create mode 100644 hacks/images/klondike/S6.png create mode 100644 hacks/images/klondike/S7.png create mode 100644 hacks/images/klondike/S8.png create mode 100644 hacks/images/klondike/S9.png create mode 100644 hacks/images/klondike/SA.png create mode 100644 hacks/images/klondike/SJ.png create mode 100644 hacks/images/klondike/SK.png create mode 100644 hacks/images/klondike/SQ.png create mode 100644 hacks/images/klondike/ST.png create mode 100644 hacks/images/klondike/attribution.txt create mode 100644 hacks/images/klondike/back.png create mode 100644 hacks/images/klondike/back0.png diff --git a/Makefile.in b/Makefile.in index c713f1f5..e5a2af25 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in --- xscreensaver, Copyright © 1999-2024 Jamie Zawinski. +# Makefile.in --- xscreensaver, Copyright © 1999-2025 Jamie Zawinski. # the `../configure' script generates `Makefile' from this file. @SET_MAKE@ @@ -167,7 +167,7 @@ bump-version:: MAJOR="$$1"; MINOR="$$2"; SUF="$$3"; \ VERS="$$MAJOR.$$MINOR$$SUF" ; \ if [ -z "$$SUF" ]; then \ - MINOR=`echo $$MINOR + 1 | bc | sed 's/^\(.\)/0\1/'` ; \ + MINOR=`echo $$MINOR + 1 | bc | sed 's/^\(.\)$$/0\1/'` ; \ else \ set - `echo $$SUF | sed 's/^\([^0-9]*\)/\1 /'` ; \ AA="$$1"; BB="$$2"; \ @@ -435,6 +435,7 @@ install_links:: cwd=`pwd` ; \ for d in $(SUBDIRS) ; do ( \ cd $$d ; \ + set -e ; \ $(MAKE2) install -k INSTALL=true INSTALL_DATA=true \ INSTALL_DIRS=false SUID_FLAGS= 2>&- | \ while read s ; do \ @@ -442,6 +443,8 @@ install_links:: if [ $$1 = true ]; then \ a="$$cwd/$$d/$$2" ; \ b="$$3" ; \ + d2=`dirname "$$b"` ; \ + [ -d "$$d2" ] || mkdir -p "$$d2" ; \ a=`echo "$$a" | sed -e 's@/\./@/@' \ -e 's@/[^/]*/\.\./@/@'` ; \ echo "ln -sf $$a $$b" ; \ @@ -452,7 +455,7 @@ install_links:: cerebrum:: - rsync -vax . 10.0.1.12:xscreensaver/ \ + rsync -vax . 10.0.1.37:xscreensaver/ \ --omit-dir-times \ --delete-during \ --exclude .git \ diff --git a/OSX/README b/OSX/README index 7bfd6255..ab027b0a 100644 --- a/OSX/README +++ b/OSX/README @@ -109,7 +109,7 @@ Building for older operating systems: 8. Scheme / Profile / Info: Executable: SaverTester.app. Scheme / Run / Info: Executable: SaverTester.app. 9: Scheme / Run / Arguments: set SELECTED_SAVER environment variable. - 10: File / Add Files / the new .c and .xml. + 10: File / Add Files / [x] Reference In Place / the new .c and .xml. Add To Targets: the new target, and "XScreenSaver-iOS" and "-tvOS". 11: Re-order the two files in the file list on the left. 12: The files might not have moved. This means Xcode is gonna crash soon. @@ -124,5 +124,5 @@ Building for older operating systems: ~/Library/Screen\ Savers/ 18: git add xscreensaver.xcodeproj/xcshareddata/xcschemes/*.xcscheme 19: Create a man page from the XML with xml2man.pl, and update Makefile.in. - 20: Upload a YouTube video: -record-animation 3600 -geom 1920x1080+128+64 + 20: Upload a YouTube video: -record-animation 2min -geom 1920x1080+128+64 ./upload-video.pl NAME diff --git a/OSX/Randomizer.plist b/OSX/Randomizer.plist index 2c39711f..27ade404 100644 --- a/OSX/Randomizer.plist +++ b/OSX/Randomizer.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.09 + 6.10 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,12 +25,12 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.09 + 6.10 CFBundleLongVersionString - 6.09 + 6.10 CFBundleGetInfoString - 6.09 + 6.10 NSHumanReadableCopyright - 6.09 + 6.10 diff --git a/OSX/SaverRunner.m b/OSX/SaverRunner.m index 233e6267..44da19f0 100644 --- a/OSX/SaverRunner.m +++ b/OSX/SaverRunner.m @@ -1517,6 +1517,7 @@ FAIL: # ifndef HAVE_IPHONE int window_count = ([saverNames count] <= 1 ? 1 : 2); + NSMutableArray *a = [[NSMutableArray arrayWithCapacity: window_count+1] retain]; windows = a; diff --git a/OSX/SaverRunner.plist b/OSX/SaverRunner.plist index 7f764c37..97da3084 100644 --- a/OSX/SaverRunner.plist +++ b/OSX/SaverRunner.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.09 + 6.10 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,13 +25,13 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.09 + 6.10 CFBundleLongVersionString - 6.09 + 6.10 CFBundleGetInfoString - 6.09 + 6.10 NSHumanReadableCopyright - 6.09 + 6.10 NSMainNibFile SaverRunner CFBundleIconFile diff --git a/OSX/Updater.plist b/OSX/Updater.plist index 5f6d8e7a..7d1071e5 100644 --- a/OSX/Updater.plist +++ b/OSX/Updater.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.09 + 6.10 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,13 +25,13 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.09 + 6.10 CFBundleLongVersionString - 6.09 + 6.10 CFBundleGetInfoString - 6.09 + 6.10 NSHumanReadableCopyright - 6.09 + 6.10 NSMainNibFile Updater CFBundleIconFile diff --git a/OSX/XScreenSaver.plist b/OSX/XScreenSaver.plist index d8269a00..e86aaa0e 100644 --- a/OSX/XScreenSaver.plist +++ b/OSX/XScreenSaver.plist @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 6.09 + 6.10 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSPrincipalClass @@ -25,13 +25,13 @@ LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.09 + 6.10 CFBundleLongVersionString - 6.09 + 6.10 CFBundleGetInfoString - 6.09 + 6.10 NSHumanReadableCopyright - 6.09 + 6.10 NSMainNibFile SaverRunner diff --git a/OSX/bindist.rtf b/OSX/bindist.rtf index 0e3d791b..03628968 100644 --- a/OSX/bindist.rtf +++ b/OSX/bindist.rtf @@ -16,14 +16,14 @@ \b0 by Jamie Zawinski\ and many others\ \ -version 6.09\ -07-Jun-2024\ +version 6.10\ +27-Apr-2025\ \ {\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 https://www.jwz.org/xscreensaver/}}\ \pard\pardeftab720 \cf0 \ -\b To install all 250+ screen savers:\ +\b To install all 260+ screen savers:\ \pard\pardeftab720\li360 \b0 \cf0 \ @@ -84,12 +84,13 @@ available there.\ \pard\pardeftab720\li360 \b0 \cf0 \ -XScreenSaver also runs on iOS and Android. The iOS version is available in the +XScreenSaver also runs on iOS and Android. Free downloads in the {\field{\*\fldinst{HYPERLINK "https://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}} -{\fldrslt \cf2 \ul \ulc2 iTunes App Store}} -and the Android version is available in the +{\fldrslt \cf2 \ul \ulc2 Apple Store}} +and on the {\field{\*\fldinst{HYPERLINK - "https://play.google.com/store/apps/details?id=org.jwz.android.xscreensaver"}} -{\fldrslt \cf2 \ul \ulc2 Google Play Store}}, and they're both free! + "https://www.jwz.org/xscreensaver/"}} +{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}, +respectively. } diff --git a/OSX/bindist2.webloc b/OSX/bindist2.webloc index 4b87f8ca..0ebfa919 100644 --- a/OSX/bindist2.webloc +++ b/OSX/bindist2.webloc @@ -3,6 +3,6 @@ URL - https://play.google.com/store/apps/details?id=org.jwz.android.xscreensaver + https://www.jwz.org/xscreensaver/download.html diff --git a/OSX/iSaverRunner.plist b/OSX/iSaverRunner.plist index e000aeb6..2495d6c2 100644 --- a/OSX/iSaverRunner.plist +++ b/OSX/iSaverRunner.plist @@ -17,17 +17,17 @@ CFBundleSignature ???? CFBundleVersion - 6.09 + 6.10 LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.09 + 6.10 CFBundleLongVersionString - 6.09 + 6.10 CFBundleGetInfoString - 6.09 + 6.10 NSHumanReadableCopyright - 6.09 + 6.10 NSMainNibFile iSaverRunner CFBundleDisplayName diff --git a/OSX/installer.rtf b/OSX/installer.rtf index 2ac08178..391ddd19 100644 --- a/OSX/installer.rtf +++ b/OSX/installer.rtf @@ -25,10 +25,10 @@ XScreenSaver also runs on iOS and Android. Free downloads in the {\field{\*\fldinst{HYPERLINK "https://itunes.apple.com/app/xscreensaver/id539014593?mt=8"}} {\fldrslt \cf2 \ul \ulc2 Apple Store}} -and +and on the {\field{\*\fldinst{HYPERLINK - "https://play.google.com/store/apps/details?id=org.jwz.android.xscreensaver"}} -{\fldrslt \cf2 \ul \ulc2 Google Store}} + "https://www.jwz.org/xscreensaver/"}} +{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}, respectively. Source code for all versions is available on the {\field{\*\fldinst{HYPERLINK "https://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 XScreenSaver web site}}. } diff --git a/OSX/ios-function-table.m b/OSX/ios-function-table.m index 12f14dea..716b9106 100644 --- a/OSX/ios-function-table.m +++ b/OSX/ios-function-table.m @@ -1,5 +1,5 @@ /* Generated file, do not edit. - Created: Mon May 6 11:02:53 2024 by build-fntable.pl 1.14. + Created: Sun Apr 27 13:13:54 2025 by build-fntable.pl 1.14. */ #import @@ -72,6 +72,7 @@ extern struct xscreensaver_function_table dnalogo_xscreensaver_function_table, drift_xscreensaver_function_table, droste_xscreensaver_function_table, + dumpsterfire_xscreensaver_function_table, dymaxionmap_xscreensaver_function_table, endgame_xscreensaver_function_table, energystream_xscreensaver_function_table, @@ -126,6 +127,7 @@ extern struct xscreensaver_function_table highvoltage_xscreensaver_function_table, hilbert_xscreensaver_function_table, hopalong_xscreensaver_function_table, + hopffibration_xscreensaver_function_table, hydrostat_xscreensaver_function_table, hypertorus_xscreensaver_function_table, hypnowheel_xscreensaver_function_table, @@ -142,6 +144,7 @@ extern struct xscreensaver_function_table kaleidocycle_xscreensaver_function_table, kallisti_xscreensaver_function_table, klein_xscreensaver_function_table, + klondike_xscreensaver_function_table, kumppa_xscreensaver_function_table, lament_xscreensaver_function_table, lavalite_xscreensaver_function_table, @@ -178,6 +181,7 @@ extern struct xscreensaver_function_table piecewise_xscreensaver_function_table, pinion_xscreensaver_function_table, pipes_xscreensaver_function_table, + platonicfolding_xscreensaver_function_table, polyhedra_xscreensaver_function_table, polyominoes_xscreensaver_function_table, polytopes_xscreensaver_function_table, @@ -329,6 +333,7 @@ NSDictionary *make_function_table_dict(void) { @"DNA Logo": [NSValue valueWithPointer:&dnalogo_xscreensaver_function_table], @"Drift": [NSValue valueWithPointer:&drift_xscreensaver_function_table], @"Droste": [NSValue valueWithPointer:&droste_xscreensaver_function_table], + @"Dumpster Fire": [NSValue valueWithPointer:&dumpsterfire_xscreensaver_function_table], @"Dymaxion Map": [NSValue valueWithPointer:&dymaxionmap_xscreensaver_function_table], @"Endgame": [NSValue valueWithPointer:&endgame_xscreensaver_function_table], @"Energy Stream": [NSValue valueWithPointer:&energystream_xscreensaver_function_table], @@ -383,6 +388,7 @@ NSDictionary *make_function_table_dict(void) { @"High Voltage": [NSValue valueWithPointer:&highvoltage_xscreensaver_function_table], @"Hilbert": [NSValue valueWithPointer:&hilbert_xscreensaver_function_table], @"Hopalong": [NSValue valueWithPointer:&hopalong_xscreensaver_function_table], + @"Hopf Fibration": [NSValue valueWithPointer:&hopffibration_xscreensaver_function_table], @"Hydrostat": [NSValue valueWithPointer:&hydrostat_xscreensaver_function_table], @"Hypertorus": [NSValue valueWithPointer:&hypertorus_xscreensaver_function_table], @"Hypnowheel": [NSValue valueWithPointer:&hypnowheel_xscreensaver_function_table], @@ -399,6 +405,7 @@ NSDictionary *make_function_table_dict(void) { @"Kaleidocycle": [NSValue valueWithPointer:&kaleidocycle_xscreensaver_function_table], @"Kallisti": [NSValue valueWithPointer:&kallisti_xscreensaver_function_table], @"Klein": [NSValue valueWithPointer:&klein_xscreensaver_function_table], + @"Klondike": [NSValue valueWithPointer:&klondike_xscreensaver_function_table], @"Kumppa": [NSValue valueWithPointer:&kumppa_xscreensaver_function_table], @"Lament": [NSValue valueWithPointer:&lament_xscreensaver_function_table], @"Lavalite": [NSValue valueWithPointer:&lavalite_xscreensaver_function_table], @@ -435,6 +442,7 @@ NSDictionary *make_function_table_dict(void) { @"Piecewise": [NSValue valueWithPointer:&piecewise_xscreensaver_function_table], @"Pinion": [NSValue valueWithPointer:&pinion_xscreensaver_function_table], @"Pipes": [NSValue valueWithPointer:&pipes_xscreensaver_function_table], + @"Platonic Folding": [NSValue valueWithPointer:&platonicfolding_xscreensaver_function_table], @"Polyhedra": [NSValue valueWithPointer:&polyhedra_xscreensaver_function_table], @"Polyominoes": [NSValue valueWithPointer:&polyominoes_xscreensaver_function_table], @"Polytopes": [NSValue valueWithPointer:&polytopes_xscreensaver_function_table], diff --git a/OSX/perl-minimize.pl b/OSX/perl-minimize.pl new file mode 100755 index 00000000..bbfc5d3c --- /dev/null +++ b/OSX/perl-minimize.pl @@ -0,0 +1,139 @@ +#!/opt/local/bin/perl -w +# Copyright © 2025 Jamie Zawinski +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. No representations are made about the suitability of this +# software for any purpose. It is provided "as is" without express or +# implied warranty. +# +# Created: 25-Feb-2025. + +require 5; +use diagnostics; +use strict; + +my $progname = $0; $progname =~ s@.*/@@g; +my ($version) = ('$Revision: 1.2 $' =~ m/\s(\d[.\d]+)\s/s); + +my $verbose = 0; + +BEGIN { eval 'use Perl::Tidy;' } + +sub minimize($$) { + my ($in, $out) = @_; + + if (!defined($Perl::Tidy::VERSION)) { + print STDERR "$progname: Perl::Tidy not installed, skipping...\n"; + return; + } + + open (my $inf, "<:utf8", $in) || error ("$in: $!"); + local $/ = undef; # read entire file + my $body = <$inf>; + close $inf; + + my $body2; + my $err = Perl::Tidy::perltidy ( + argv => join (' ', + '--mangle', + '--delete-all-comments', + ), + source => \$body, + destination => \$body2, + ); + error ($err) if $err; + + # Find all functions and variables, and shorten them. + # + my @subs = ($body2 =~ m/ \b sub \s+ ([a-zA-Z\d_]+) \s* [\{\(] /gsx); + my @vars = ($body2 =~ m/ \b my \s* [\$#%@] ([a-zA-Z\d_]+) [\s;,=] /gsx); + my @args = ($body2 =~ m/ \b my \s* \( ( .*? ) \) /gsx); + + foreach my $tt (@args) { + foreach my $t (split (/\s*,\s*/, $tt)) { + $t =~ s/^[\$#%@]//s; + $t =~ s/=.*//s; + push @vars, $t; + } + } + + my %tokens; + my $i = 0; + foreach my $t (@vars) { + if (length($t) < 4) { + print STDERR "$progname: skip var $t\n" if ($verbose > 1); + next; + } + $tokens{$t} = sprintf ("V%X", $i++); + } + + $i = 0; + foreach my $t (@subs) { + if (length($t) < 4) { + print STDERR "$progname: skip sub $t\n" if ($verbose > 1); + next; + } + next if (length($t) < 4); + $tokens{$t} = sprintf ("F%X", $i++); + } + + foreach my $k (sort keys %tokens) { + my $v = $tokens{$k}; + if ($v =~ m/^S/) { + $body2 =~ s/ ( [^a-zA-Z\d_] ) ( $k ) ( [^a-zA-Z\d_] ) /$1$v$3/gsx; + } else { + $body2 =~ s/ ( [\$#%@] \{? ) ( $k ) ( [^a-zA-Z\d_] ) /$1$v$3/gsx; + } + print STDERR "$progname: $k => $v\n" if ($verbose > 1); + } + + $in =~ s@^.*/@@s; + my $tag = "# DO NOT EDIT -- auto-generated from \"$in\"\n\n"; + $body2 =~ s/^([^\n]+\n)/$1$tag/s; + + $body2 =~ s/\n\n+/\n/gs; # Why is it double-spaced? + + if ($out eq '-') { + print STDOUT $body2; + } else { + open (my $outf, ">:utf8", $out) || error ("$out: $!"); + print $outf $body2; + close $outf; + print STDERR "$progname: wrote $out\n"; + } +} + + +sub error($) { + my ($err) = @_; + print STDERR "$progname: $err\n"; + exit 1; +} + +sub usage() { + print STDERR "usage: $progname [--verbose] in.pl out.pl\n"; + exit 1; +} + +sub main() { + my ($in, $out); + while (@ARGV) { + $_ = shift @ARGV; + if (m/^--?verbose$/s) { $verbose++; } + elsif (m/^-v+$/s) { $verbose += length($_)-1; } +# elsif (m/^--?debug$/s) { $debug_p++; } + elsif (m/^-./s) { usage; } + elsif (!$in) { $in = $_; } + elsif (!$out) { $out = $_; } + else { usage; } + } + + usage unless ($out); + minimize ($in, $out); +} + +main(); +exit 0; diff --git a/OSX/tvSaverRunner.plist b/OSX/tvSaverRunner.plist index 474b047e..9bc514e0 100644 --- a/OSX/tvSaverRunner.plist +++ b/OSX/tvSaverRunner.plist @@ -17,17 +17,17 @@ CFBundleSignature ???? CFBundleVersion - 6.09 + 6.10 LSApplicationCategoryType public.app-category.entertainment CFBundleShortVersionString - 6.09 + 6.10 CFBundleLongVersionString - 6.09 + 6.10 CFBundleGetInfoString - 6.09 + 6.10 NSHumanReadableCopyright - 6.09 + 6.10 CFBundleDisplayName ${PRODUCT_NAME} CFBundleIcons diff --git a/OSX/update-info-plist.pl b/OSX/update-info-plist.pl index ccb86a2c..b8e09ef7 100755 --- a/OSX/update-info-plist.pl +++ b/OSX/update-info-plist.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright © 2006-2023 Jamie Zawinski +# Copyright © 2006-2025 Jamie Zawinski # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that @@ -27,7 +27,7 @@ use IO::Compress::Gzip qw(gzip $GzipError); my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@); -my ($version) = ('$Revision: 1.58 $' =~ m/\s(\d[.\d]+)\s/s); +my ($version) = ('$Revision: 1.60 $' =~ m/\s(\d[.\d]+)\s/s); $ENV{PATH} = "/usr/local/bin:$ENV{PATH}"; # for seticon $ENV{PATH} = "/opt/local/bin:$ENV{PATH}"; # for macports wget @@ -306,6 +306,30 @@ sub compress_all_xml_files($) { } +sub minimize_scripts($) { + my ($dir) = @_; + my $d2 = $dir . '/Contents/Resources'; + $dir = $d2 if (-d $d2); + opendir (my $dirp, $dir) || error ("$dir: $!"); + my @files = readdir ($dirp); + closedir $dirp; + foreach my $f (sort @files) { + next if ($f =~ m/^\./s); + next if ($f eq 'XScreenSaver'); + $f = "$dir/$f"; + next if ($f =~ m/\.(xml|png|jpg|ttf)$/s); + next if (-d $f); + next unless (-x $f); # Assume executable files are Perl scripts + my @cmd = "$exec_dir/perl-minimize.pl"; + push @cmd, '--verbose' if ($verbose > 2); + push @cmd, ($f, $f); + print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" + if ($verbose > 1); + system (@cmd); + } +} + + sub set_plist_key($$$$) { my ($filename, $body, $key, $val) = @_; @@ -395,9 +419,6 @@ sub update($) { my $vers = $1; my ($ignore, $info_str, $name) = update_saver_xml ($app_dir, $vers); - # No, don't do this -- the iOS version reads the XML file in a few - # different places, and most of those places don't understand gzip. - if ($app_name eq 'XScreenSaver') { compress_all_xml_files ($app_dir); } else { @@ -450,6 +471,8 @@ sub update($) { } } + minimize_scripts ($app_dir); + # MacOS 10.12: codesign says "resource fork, Finder information, or # similar detritus not allowed" if any bundle has an Icon\r file. # set_icon ($app_dir); diff --git a/OSX/updates.xml b/OSX/updates.xml index 3279d9c0..1971a9a1 100644 --- a/OSX/updates.xml +++ b/OSX/updates.xml @@ -7,6 +7,17 @@ https://www.jwz.org/xscreensaver/updates.xml Updates to xscreensaver. en + + Version 6.10 + https://www.jwz.org/xscreensaver/xscreensaver-6.10.dmg + • Rewrote the VT100 emulator for 'apple2' and 'phosphor'. Supports inverse and DEC Special Graphics.
• BSOD supports systemd and bitlocker. ]]>
+ Sun, 27 Apr 2025 17:04:18 -0700 + +
Version 6.09 https://www.jwz.org/xscreensaver/xscreensaver-6.09.dmg @@ -18,16 +29,5 @@ length="90634351" type="application/octet-stream" /> - - Version 6.07 - https://www.jwz.org/xscreensaver/xscreensaver-6.07.dmg - • `xscreensaver-settings' was sometimes turning off the DPMS checkbox.
• Log pid of caller of `deactivate' command, to give a hint about who is preventing the screen from blanking.
• recanim uses libffmpeg.
• Updates to `sphereeversion'.
• Added some new map sources to `mapscroller'.
• Worked around a macOS 13.4 bug where multi-head systems would fail to launch savers on some or all screens.
• Minimum compiler target is now ISO C99 instead of ANSI C89. Didn't want to rush into it.
• macOS, Android: Better looking thunbmail images.
• Various other minor bug fixes.]]>
- Tue, 29 Aug 2023 18:06:48 -0700 - -
diff --git a/OSX/xscreensaver.xcodeproj/project.pbxproj b/OSX/xscreensaver.xcodeproj/project.pbxproj index d0ea840f..7d6d4b60 100644 --- a/OSX/xscreensaver.xcodeproj/project.pbxproj +++ b/OSX/xscreensaver.xcodeproj/project.pbxproj @@ -222,6 +222,7 @@ AFF449FE22754B5600DB8EDB /* PBXTargetDependency */, AF3938381D0FBF5300205406 /* PBXTargetDependency */, AF777A3F09B660B500EA3033 /* PBXTargetDependency */, + AFCB48BB2DBC0C3E006296D3 /* PBXTargetDependency */, AFEC23EB1CB6ED0800DE138F /* PBXTargetDependency */, AF777A3D09B660B500EA3033 /* PBXTargetDependency */, AFACE8911CC8365F008B24CD /* PBXTargetDependency */, @@ -255,6 +256,7 @@ AF1B0FC51D7AB5740011DBE4 /* PBXTargetDependency */, AF0BF6ED29456D50000D9473 /* PBXTargetDependency */, AF42CF712BE8A56100675AC7 /* PBXTargetDependency */, + AFA82E402DB1ECC600BEEE3E /* PBXTargetDependency */, AF4F10F0143450C300E34F3F /* PBXTargetDependency */, AFC0E8C91CDC6125008CAFAC /* PBXTargetDependency */, AF777A1709B660B300EA3033 /* PBXTargetDependency */, @@ -265,6 +267,7 @@ AFBFE7421786407000432B21 /* PBXTargetDependency */, AFC644742AE47A1000D589B9 /* PBXTargetDependency */, AF777A1109B660B300EA3033 /* PBXTargetDependency */, + AF2D86B82DB2105300B4F248 /* PBXTargetDependency */, AF777A0F09B660B200EA3033 /* PBXTargetDependency */, AF777A0D09B660B200EA3033 /* PBXTargetDependency */, AF4FD6FF0CE7A4F9005EE58E /* PBXTargetDependency */, @@ -284,6 +287,7 @@ AFD51B350F063B7800471C02 /* PBXTargetDependency */, AF7779FF09B660B200EA3033 /* PBXTargetDependency */, AF7779FD09B660B100EA3033 /* PBXTargetDependency */, + AF2D86942DB2032D00B4F248 /* PBXTargetDependency */, AF7779FB09B660B100EA3033 /* PBXTargetDependency */, AF7779F909B660B100EA3033 /* PBXTargetDependency */, AFFAB33519158F1E0020F021 /* PBXTargetDependency */, @@ -1618,6 +1622,39 @@ AF2D0D40241D7D7F0001D8B8 /* etruscanvenus.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D0D3F241D7D7F0001D8B8 /* etruscanvenus.c */; }; AF2D0D41241D7D7F0001D8B8 /* etruscanvenus.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D0D3F241D7D7F0001D8B8 /* etruscanvenus.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; AF2D29E6270BE727000B8588 /* tvLaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AF2D29E5270BE726000B8588 /* tvLaunchScreen.storyboard */; }; + AF2D867A2DB1FCC900B4F248 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; + AF2D867C2DB1FCC900B4F248 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; }; + AF2D867D2DB1FCC900B4F248 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; }; + AF2D867E2DB1FCC900B4F248 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; }; + AF2D867F2DB1FCC900B4F248 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + AF2D86802DB1FCC900B4F248 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; }; + AF2D86812DB1FCC900B4F248 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; }; + AF2D86822DB1FCC900B4F248 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; }; + AF2D868B2DB1FDB900B4F248 /* platonicfolding.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86892DB1FDB900B4F248 /* platonicfolding.c */; }; + AF2D868C2DB1FDB900B4F248 /* platonicfolding.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF2D868A2DB1FDB900B4F248 /* platonicfolding.xml */; }; + AF2D868D2DB1FDB900B4F248 /* platonicfolding.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF2D868A2DB1FDB900B4F248 /* platonicfolding.xml */; }; + AF2D868E2DB1FDB900B4F248 /* platonicfolding.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86892DB1FDB900B4F248 /* platonicfolding.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AF2D868F2DB1FDB900B4F248 /* platonicfolding.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF2D868A2DB1FDB900B4F248 /* platonicfolding.xml */; }; + AF2D86902DB1FDB900B4F248 /* platonicfolding.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86892DB1FDB900B4F248 /* platonicfolding.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AF2D86912DB2013200B4F248 /* xftwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFBD953C2C504ADC000DA52A /* xftwrap.c */; }; + AF2D86922DB2014100B4F248 /* xftwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFBD953C2C504ADC000DA52A /* xftwrap.c */; }; + AF2D869C2DB20F2100B4F248 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; + AF2D869E2DB20F2100B4F248 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; }; + AF2D869F2DB20F2100B4F248 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; }; + AF2D86A02DB20F2100B4F248 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; }; + AF2D86A12DB20F2100B4F248 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + AF2D86A22DB20F2100B4F248 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; }; + AF2D86A32DB20F2100B4F248 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; }; + AF2D86A42DB20F2100B4F248 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; }; + AF2D86AE2DB2100A00B4F248 /* klondike.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AB2DB2100A00B4F248 /* klondike.c */; }; + AF2D86AF2DB2100A00B4F248 /* klondike-game.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AD2DB2100A00B4F248 /* klondike-game.c */; }; + AF2D86B02DB2100A00B4F248 /* klondike.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF2D86AC2DB2100A00B4F248 /* klondike.xml */; }; + AF2D86B12DB2100A00B4F248 /* klondike.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF2D86AC2DB2100A00B4F248 /* klondike.xml */; }; + AF2D86B22DB2100A00B4F248 /* klondike.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AB2DB2100A00B4F248 /* klondike.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AF2D86B32DB2100A00B4F248 /* klondike-game.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AD2DB2100A00B4F248 /* klondike-game.c */; }; + AF2D86B42DB2100A00B4F248 /* klondike.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF2D86AC2DB2100A00B4F248 /* klondike.xml */; }; + AF2D86B52DB2100A00B4F248 /* klondike.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AB2DB2100A00B4F248 /* klondike.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AF2D86B62DB2100A00B4F248 /* klondike-game.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D86AD2DB2100A00B4F248 /* klondike-game.c */; }; AF2D8F321CEBA10300198014 /* jwxyz-timers.c in Sources */ = {isa = PBXBuildFile; fileRef = AF2D8F301CEBA10300198014 /* jwxyz-timers.c */; }; AF2D8F331CEBA10300198014 /* jwxyz-timers.h in Headers */ = {isa = PBXBuildFile; fileRef = AF2D8F311CEBA10300198014 /* jwxyz-timers.h */; }; AF32D9E70F3AD0B40080F535 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; @@ -2522,6 +2559,10 @@ AF5C9B121A0CCF4E00B0147A /* cityflow.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF5C9B0F1A0CCF4E00B0147A /* cityflow.xml */; }; AF5C9B131A0CCF4E00B0147A /* cityflow.c in Sources */ = {isa = PBXBuildFile; fileRef = AF5C9B101A0CCF4E00B0147A /* cityflow.c */; }; AF5C9B141A0CCF4E00B0147A /* cityflow.c in Sources */ = {isa = PBXBuildFile; fileRef = AF5C9B101A0CCF4E00B0147A /* cityflow.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AF5D4E3C2D6409AE009BE57E /* ansi-tty.c in Sources */ = {isa = PBXBuildFile; fileRef = AF5D4E3B2D6409AE009BE57E /* ansi-tty.c */; }; + AF5D4E3D2D6409AE009BE57E /* ansi-tty.c in Sources */ = {isa = PBXBuildFile; fileRef = AF5D4E3B2D6409AE009BE57E /* ansi-tty.c */; }; + AF5D4E3E2D6409AE009BE57E /* ansi-tty.c in Sources */ = {isa = PBXBuildFile; fileRef = AF5D4E3B2D6409AE009BE57E /* ansi-tty.c */; }; + AF5D4E3F2D6409AE009BE57E /* ansi-tty.c in Sources */ = {isa = PBXBuildFile; fileRef = AF5D4E3B2D6409AE009BE57E /* ansi-tty.c */; }; AF5ECEB02116B1A400069433 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; AF5ECEB12116B1A400069433 /* analogtv.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4CFA09B5AC94006E59CF /* analogtv.c */; }; AF5ECEB42116B1A400069433 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; }; @@ -3971,6 +4012,23 @@ AFA6AAFF20999950006D2685 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; }; AFA6AB0D20999A60006D2685 /* glitchpeg.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFA6AB0C20999A60006D2685 /* glitchpeg.xml */; }; AFA6AB0F20999A7B006D2685 /* glitchpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA6AB0E20999A7B006D2685 /* glitchpeg.c */; }; + AFA82E242DB1EB4B00BEEE3E /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; + AFA82E262DB1EB4B00BEEE3E /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; }; + AFA82E272DB1EB4B00BEEE3E /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; }; + AFA82E282DB1EB4B00BEEE3E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; }; + AFA82E292DB1EB4B00BEEE3E /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + AFA82E2A2DB1EB4B00BEEE3E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; }; + AFA82E2B2DB1EB4B00BEEE3E /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; }; + AFA82E2C2DB1EB4B00BEEE3E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; }; + AFA82E362DB1EC3B00BEEE3E /* hopffibration.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFA82E352DB1EC3B00BEEE3E /* hopffibration.xml */; }; + AFA82E372DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA82E342DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFA82E382DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA82E332DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFA82E392DB1EC3B00BEEE3E /* hopffibration.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFA82E352DB1EC3B00BEEE3E /* hopffibration.xml */; }; + AFA82E3A2DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA82E342DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c */; }; + AFA82E3B2DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA82E332DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c */; }; + AFA82E3C2DB1EC3B00BEEE3E /* hopffibration.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFA82E352DB1EC3B00BEEE3E /* hopffibration.xml */; }; + AFA82E3D2DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA82E342DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFA82E3E2DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c in Sources */ = {isa = PBXBuildFile; fileRef = AFA82E332DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; AFAA6B451773F07800DE720C /* ios-function-table.m in Sources */ = {isa = PBXBuildFile; fileRef = AFAA6B441773F07700DE720C /* ios-function-table.m */; }; AFAAE38E207D6343007A515C /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; AFAAE390207D6343007A515C /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; }; @@ -4037,6 +4095,7 @@ AFB8A69B1782BA34004EDB85 /* kaleidocycle.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFB8A69A1782BA34004EDB85 /* kaleidocycle.xml */; }; AFB8A69C1782BF6C004EDB85 /* kaleidocycle.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFB8A69A1782BA34004EDB85 /* kaleidocycle.xml */; }; AFB8A69D1782BFA6004EDB85 /* kaleidocycle.c in Sources */ = {isa = PBXBuildFile; fileRef = AF7511141782B64300380EA1 /* kaleidocycle.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFBD953D2C504AFC000DA52A /* xftwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = AFBD953C2C504ADC000DA52A /* xftwrap.c */; }; AFBE744019A7C6930018AA35 /* robot.c in Sources */ = {isa = PBXBuildFile; fileRef = AFBE743F19A7C6930018AA35 /* robot.c */; }; AFBE744119A7C6EF0018AA35 /* robot.c in Sources */ = {isa = PBXBuildFile; fileRef = AFBE743F19A7C6930018AA35 /* robot.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; AFBF893E0E41D930006A2D66 /* fps.c in Sources */ = {isa = PBXBuildFile; fileRef = AFBF893C0E41D930006A2D66 /* fps.c */; }; @@ -4116,6 +4175,23 @@ AFC7592E158D8E8B00C5458E /* textclient.h in Headers */ = {isa = PBXBuildFile; fileRef = AFC7592C158D8E8B00C5458E /* textclient.h */; }; AFC75930158D9A7A00C5458E /* textclient-ios.m in Sources */ = {isa = PBXBuildFile; fileRef = AFC7592F158D9A7A00C5458E /* textclient-ios.m */; }; AFCA3EED25856B6200CBCF16 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFCA3EEC25856B6200CBCF16 /* IOKit.framework */; }; + AFCB489F2DBC0958006296D3 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; }; + AFCB48A12DBC0958006296D3 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; }; + AFCB48A22DBC0958006296D3 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; }; + AFCB48A32DBC0958006296D3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF2C31E515C0F7FE007A6896 /* QuartzCore.framework */; }; + AFCB48A42DBC0958006296D3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + AFCB48A52DBC0958006296D3 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; }; + AFCB48A62DBC0958006296D3 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE0BC611A6B0D6200C098BF /* OpenGL.framework */; }; + AFCB48A72DBC0958006296D3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AF78369617DB9F25003B9FC0 /* libz.dylib */; }; + AFCB48B12DBC0BDB006296D3 /* dumpster_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFCB48AE2DBC0BDB006296D3 /* dumpster_model.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFCB48B22DBC0BDB006296D3 /* dumpsterfire.c in Sources */ = {isa = PBXBuildFile; fileRef = AFCB48AF2DBC0BDB006296D3 /* dumpsterfire.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFCB48B32DBC0BDB006296D3 /* dumpsterfire.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCB48B02DBC0BDB006296D3 /* dumpsterfire.xml */; }; + AFCB48B42DBC0BDB006296D3 /* dumpsterfire.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCB48B02DBC0BDB006296D3 /* dumpsterfire.xml */; }; + AFCB48B52DBC0BDB006296D3 /* dumpster_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFCB48AE2DBC0BDB006296D3 /* dumpster_model.c */; }; + AFCB48B62DBC0BDB006296D3 /* dumpsterfire.c in Sources */ = {isa = PBXBuildFile; fileRef = AFCB48AF2DBC0BDB006296D3 /* dumpsterfire.c */; }; + AFCB48B72DBC0BDB006296D3 /* dumpster_model.c in Sources */ = {isa = PBXBuildFile; fileRef = AFCB48AE2DBC0BDB006296D3 /* dumpster_model.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFCB48B82DBC0BDB006296D3 /* dumpsterfire.c in Sources */ = {isa = PBXBuildFile; fileRef = AFCB48AF2DBC0BDB006296D3 /* dumpsterfire.c */; settings = {COMPILER_FLAGS = "-DUSE_GL"; }; }; + AFCB48B92DBC0BDB006296D3 /* dumpsterfire.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCB48B02DBC0BDB006296D3 /* dumpsterfire.xml */; }; AFCCCBB009BFE4B000353F4D /* rdbomb.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */; }; AFCCCBB309BFE51900353F4D /* thornbird.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC259230988A469000655EE /* thornbird.xml */; }; AFCE26332337332000BDCE10 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AFCE26322337332000BDCE10 /* LaunchScreen.storyboard */; }; @@ -4924,6 +5000,34 @@ remoteGlobalIDString = AF2D0D25241D7C870001D8B8; remoteInfo = EtruscanVenus; }; + AF2D86742DB1FCC900B4F248 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AF4808C0098C3B6C00FB32B8; + remoteInfo = jwxyz; + }; + AF2D86932DB2032D00B4F248 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AF2D86722DB1FCC900B4F248; + remoteInfo = PlatonicFolding; + }; + AF2D86972DB20F2100B4F248 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AF4808C0098C3B6C00FB32B8; + remoteInfo = jwxyz; + }; + AF2D86B72DB2105300B4F248 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AF2D86952DB20F2100B4F248; + remoteInfo = Klondike; + }; AF32D9E20F3AD0B40080F535 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -8081,6 +8185,20 @@ remoteGlobalIDString = AFA6AAF020999950006D2685; remoteInfo = GlitchPEG; }; + AFA82E1F2DB1EB4B00BEEE3E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AF4808C0098C3B6C00FB32B8; + remoteInfo = jwxyz; + }; + AFA82E3F2DB1ECC600BEEE3E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AFA82E1D2DB1EB4B00BEEE3E; + remoteInfo = HopfFibration; + }; AFAAE389207D6343007A515C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -8277,6 +8395,20 @@ remoteGlobalIDString = AF9771D60989DC4A001F8B92; remoteInfo = SaverTester; }; + AFCB489A2DBC0958006296D3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AF4808C0098C3B6C00FB32B8; + remoteInfo = jwxyz; + }; + AFCB48BA2DBC0C3E006296D3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = AFCB48982DBC0958006296D3; + remoteInfo = DumpsterFire; + }; AFCF833D1AF5B515008BB7E1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -8905,6 +9037,13 @@ AF2D0D3F241D7D7F0001D8B8 /* etruscanvenus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = etruscanvenus.c; path = hacks/glx/etruscanvenus.c; sourceTree = ""; }; AF2D29E5270BE726000B8588 /* tvLaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = tvLaunchScreen.storyboard; sourceTree = ""; }; AF2D522513E954A0002AA818 /* SaverRunner.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = SaverRunner.icns; sourceTree = ""; }; + AF2D86872DB1FCC900B4F248 /* PlatonicFolding.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PlatonicFolding.saver; sourceTree = BUILT_PRODUCTS_DIR; }; + AF2D86892DB1FDB900B4F248 /* platonicfolding.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = platonicfolding.c; path = ../hacks/glx/platonicfolding.c; sourceTree = SOURCE_ROOT; }; + AF2D868A2DB1FDB900B4F248 /* platonicfolding.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = platonicfolding.xml; path = ../hacks/config/platonicfolding.xml; sourceTree = SOURCE_ROOT; }; + AF2D86A92DB20F2100B4F248 /* Klondike.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Klondike.saver; sourceTree = BUILT_PRODUCTS_DIR; }; + AF2D86AB2DB2100A00B4F248 /* klondike.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = klondike.c; path = ../hacks/glx/klondike.c; sourceTree = SOURCE_ROOT; }; + AF2D86AC2DB2100A00B4F248 /* klondike.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = klondike.xml; path = ../hacks/config/klondike.xml; sourceTree = SOURCE_ROOT; }; + AF2D86AD2DB2100A00B4F248 /* klondike-game.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "klondike-game.c"; path = "../hacks/glx/klondike-game.c"; sourceTree = SOURCE_ROOT; }; AF2D8F301CEBA10300198014 /* jwxyz-timers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "jwxyz-timers.c"; path = "../jwxyz/jwxyz-timers.c"; sourceTree = ""; }; AF2D8F311CEBA10300198014 /* jwxyz-timers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "jwxyz-timers.h"; path = "../jwxyz/jwxyz-timers.h"; sourceTree = ""; }; AF32D9F40F3AD0B40080F535 /* RubikBlocks.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RubikBlocks.saver; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -9120,6 +9259,7 @@ AF5C9B0D1A0CCE6E00B0147A /* Cityflow.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cityflow.saver; sourceTree = BUILT_PRODUCTS_DIR; }; AF5C9B0F1A0CCF4E00B0147A /* cityflow.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = cityflow.xml; sourceTree = ""; }; AF5C9B101A0CCF4E00B0147A /* cityflow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cityflow.c; path = hacks/glx/cityflow.c; sourceTree = ""; }; + AF5D4E3B2D6409AE009BE57E /* ansi-tty.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "ansi-tty.c"; path = "hacks/ansi-tty.c"; sourceTree = ""; }; AF5ECEC02116B1A400069433 /* VFeedback.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VFeedback.saver; sourceTree = BUILT_PRODUCTS_DIR; }; AF5ECEC22116B2CC00069433 /* vfeedback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vfeedback.c; path = hacks/vfeedback.c; sourceTree = ""; }; AF5ECEC52116B2FE00069433 /* vfeedback.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = vfeedback.xml; sourceTree = ""; }; @@ -9524,6 +9664,10 @@ AFA6AB0520999950006D2685 /* GlitchPEG.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GlitchPEG.saver; sourceTree = BUILT_PRODUCTS_DIR; }; AFA6AB0C20999A60006D2685 /* glitchpeg.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = glitchpeg.xml; sourceTree = ""; }; AFA6AB0E20999A7B006D2685 /* glitchpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = glitchpeg.c; path = hacks/glitchpeg.c; sourceTree = ""; }; + AFA82E312DB1EB4B00BEEE3E /* HopfFibration.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HopfFibration.saver; sourceTree = BUILT_PRODUCTS_DIR; }; + AFA82E332DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = hacks/glx/hopfanimations.c; sourceTree = ""; }; + AFA82E342DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = hacks/glx/hopffibration.c; sourceTree = ""; }; + AFA82E352DB1EC3B00BEEE3E /* hopffibration.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = hopffibration.xml; sourceTree = ""; }; AFAA6B441773F07700DE720C /* ios-function-table.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ios-function-table.m"; sourceTree = ""; }; AFAAE39C207D6343007A515C /* Maze3D.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Maze3D.saver; sourceTree = BUILT_PRODUCTS_DIR; }; AFAAE39E207D6420007A515C /* maze3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = maze3d.c; path = hacks/glx/maze3d.c; sourceTree = ""; }; @@ -9547,6 +9691,8 @@ AFB5A0ED0981FF8B00871B16 /* usleep.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = usleep.c; path = utils/usleep.c; sourceTree = ""; }; AFB5A0EE0981FF8B00871B16 /* usleep.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; name = usleep.h; path = utils/usleep.h; sourceTree = ""; }; AFB8A69A1782BA34004EDB85 /* kaleidocycle.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = kaleidocycle.xml; sourceTree = ""; }; + AFBD953B2C504ADB000DA52A /* xftwrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xftwrap.h; path = utils/xftwrap.h; sourceTree = ""; }; + AFBD953C2C504ADC000DA52A /* xftwrap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xftwrap.c; path = utils/xftwrap.c; sourceTree = ""; }; AFBE743F19A7C6930018AA35 /* robot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = robot.c; path = hacks/glx/robot.c; sourceTree = ""; }; AFBF893C0E41D930006A2D66 /* fps.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = fps.c; path = hacks/fps.c; sourceTree = ""; }; AFBF893D0E41D930006A2D66 /* fps.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = fps.h; path = hacks/fps.h; sourceTree = ""; }; @@ -9781,6 +9927,10 @@ AFC7592C158D8E8B00C5458E /* textclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = textclient.h; path = utils/textclient.h; sourceTree = ""; }; AFC7592F158D9A7A00C5458E /* textclient-ios.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "textclient-ios.m"; path = "OSX/textclient-ios.m"; sourceTree = ""; }; AFCA3EEC25856B6200CBCF16 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + AFCB48AC2DBC0958006296D3 /* DumpsterFire.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DumpsterFire.saver; sourceTree = BUILT_PRODUCTS_DIR; }; + AFCB48AE2DBC0BDB006296D3 /* dumpster_model.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = dumpster_model.c; path = ../hacks/glx/dumpster_model.c; sourceTree = SOURCE_ROOT; }; + AFCB48AF2DBC0BDB006296D3 /* dumpsterfire.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = dumpsterfire.c; path = ../hacks/glx/dumpsterfire.c; sourceTree = SOURCE_ROOT; }; + AFCB48B02DBC0BDB006296D3 /* dumpsterfire.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = dumpsterfire.xml; path = ../hacks/config/dumpsterfire.xml; sourceTree = SOURCE_ROOT; }; AFCCCBAD09BFE4B000353F4D /* rdbomb.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = rdbomb.xml; sourceTree = ""; }; AFCE26322337332000BDCE10 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; AFCF83501AF5B515008BB7E1 /* SplitFlap.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SplitFlap.saver; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -10133,6 +10283,34 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AF2D867B2DB1FCC900B4F248 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AF2D867C2DB1FCC900B4F248 /* libjwxyz.a in Frameworks */, + AF2D867D2DB1FCC900B4F248 /* ScreenSaver.framework in Frameworks */, + AF2D867E2DB1FCC900B4F248 /* QuartzCore.framework in Frameworks */, + AF2D867F2DB1FCC900B4F248 /* Cocoa.framework in Frameworks */, + AF2D86802DB1FCC900B4F248 /* Carbon.framework in Frameworks */, + AF2D86812DB1FCC900B4F248 /* OpenGL.framework in Frameworks */, + AF2D86822DB1FCC900B4F248 /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AF2D869D2DB20F2100B4F248 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AF2D869E2DB20F2100B4F248 /* libjwxyz.a in Frameworks */, + AF2D869F2DB20F2100B4F248 /* ScreenSaver.framework in Frameworks */, + AF2D86A02DB20F2100B4F248 /* QuartzCore.framework in Frameworks */, + AF2D86A12DB20F2100B4F248 /* Cocoa.framework in Frameworks */, + AF2D86A22DB20F2100B4F248 /* Carbon.framework in Frameworks */, + AF2D86A32DB20F2100B4F248 /* OpenGL.framework in Frameworks */, + AF2D86A42DB20F2100B4F248 /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AF32D9E80F3AD0B40080F535 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -13103,6 +13281,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AFA82E252DB1EB4B00BEEE3E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AFA82E262DB1EB4B00BEEE3E /* libjwxyz.a in Frameworks */, + AFA82E272DB1EB4B00BEEE3E /* ScreenSaver.framework in Frameworks */, + AFA82E282DB1EB4B00BEEE3E /* QuartzCore.framework in Frameworks */, + AFA82E292DB1EB4B00BEEE3E /* Cocoa.framework in Frameworks */, + AFA82E2A2DB1EB4B00BEEE3E /* Carbon.framework in Frameworks */, + AFA82E2B2DB1EB4B00BEEE3E /* OpenGL.framework in Frameworks */, + AFA82E2C2DB1EB4B00BEEE3E /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AFAAE38F207D6343007A515C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -13241,6 +13433,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AFCB48A02DBC0958006296D3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AFCB48A12DBC0958006296D3 /* libjwxyz.a in Frameworks */, + AFCB48A22DBC0958006296D3 /* ScreenSaver.framework in Frameworks */, + AFCB48A32DBC0958006296D3 /* QuartzCore.framework in Frameworks */, + AFCB48A42DBC0958006296D3 /* Cocoa.framework in Frameworks */, + AFCB48A52DBC0958006296D3 /* Carbon.framework in Frameworks */, + AFCB48A62DBC0958006296D3 /* OpenGL.framework in Frameworks */, + AFCB48A72DBC0958006296D3 /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AFCF83431AF5B515008BB7E1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14309,6 +14515,10 @@ AF70B7A32A8320A6007C1EB8 /* Skulloop.saver */, AFC644652AE478FA00D589B9 /* Kallisti.saver */, AF42CF622BE8A3B300675AC7 /* HighVoltage.saver */, + AFA82E312DB1EB4B00BEEE3E /* HopfFibration.saver */, + AF2D86872DB1FCC900B4F248 /* PlatonicFolding.saver */, + AF2D86A92DB20F2100B4F248 /* Klondike.saver */, + AFCB48AC2DBC0958006296D3 /* DumpsterFire.saver */, ); name = Products; path = ..; @@ -14668,6 +14878,8 @@ AF0839AA09930C4900277BE9 /* dolphin.c */, AF241F81107C38DF00046A84 /* dropshadow.c */, AF241F82107C38DF00046A84 /* dropshadow.h */, + AFCB48AF2DBC0BDB006296D3 /* dumpsterfire.c */, + AFCB48AE2DBC0BDB006296D3 /* dumpster_model.c */, AFEC23E41CB6EBC400DE138F /* dymaxionmap.c */, AF4C300D208569A900BE1DEF /* dymaxionmap-coords.c */, AF7778C109B65C6A00EA3033 /* e_textures.h */, @@ -14725,6 +14937,8 @@ AF42CF652BE8A50E00675AC7 /* highvoltage_model.c */, AF42CF662BE8A50E00675AC7 /* highvoltage.c */, AF78D18A142DD96E002AAF77 /* hilbert.c */, + AFA82E332DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c */, + AFA82E342DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c */, AFC0E8C21CDC60A9008CAFAC /* hydrostat.c */, AFA55F59099362DF00F3E977 /* hypertorus.c */, AF3C715D0D624C600030CC0D /* hypnowheel.c */, @@ -14737,6 +14951,8 @@ AFC644672AE479BB00D589B9 /* kallisti_model.c */, AFC644692AE479BC00D589B9 /* kallisti.c */, AFA55F3F0993626E00F3E977 /* klein.c */, + AF2D86AB2DB2100A00B4F248 /* klondike.c */, + AF2D86AD2DB2100A00B4F248 /* klondike-game.c */, AFA55A8E0993369100F3E977 /* lament.c */, AFF1BA0E19A96D8B0016A88D /* lament_model.c */, AFA55DDD09935DB600F3E977 /* lavalite.c */, @@ -14765,6 +14981,7 @@ AFA561B309937DCC00F3E977 /* polyhedra.c */, AFA561B409937DCC00F3E977 /* polyhedra.h */, AFA560C3099371D500F3E977 /* polytopes.c */, + AF2D86892DB1FDB900B4F248 /* platonicfolding.c */, AFFAB33119158EA80020F021 /* projectiveplane.c */, AFA5621C099384F600F3E977 /* providence.c */, AFA55B3F09933EC600F3E977 /* pulsar.c */, @@ -14921,6 +15138,7 @@ AFC258970988A468000655EE /* discrete.xml */, AFC258980988A468000655EE /* distort.xml */, AF77787909B6545E00EA3033 /* dnalogo.xml */, + AFCB48B02DBC0BDB006296D3 /* dumpsterfire.xml */, AFC258990988A468000655EE /* drift.xml */, AF7F06112A50C18C00E35B45 /* droste.xml */, AFEC23E51CB6EBDA00DE138F /* dymaxionmap.xml */, @@ -14983,6 +15201,7 @@ AF42CF642BE8A50E00675AC7 /* highvoltage.xml */, AF78D18E142DD99A002AAF77 /* hilbert.xml */, AFC258C50988A468000655EE /* hopalong.xml */, + AFA82E352DB1EC3B00BEEE3E /* hopffibration.xml */, AFC258C60988A468000655EE /* hyperball.xml */, AFC0E8C31CDC60A9008CAFAC /* hydrostat.xml */, AFC258C70988A468000655EE /* hypercube.xml */, @@ -15003,6 +15222,7 @@ AFB8A69A1782BA34004EDB85 /* kaleidocycle.xml */, AFC644682AE479BB00D589B9 /* kallisti.xml */, AFC258D40988A468000655EE /* klein.xml */, + AF2D86AC2DB2100A00B4F248 /* klondike.xml */, AFC258D50988A468000655EE /* kumppa.xml */, AFC258D60988A468000655EE /* lament.xml */, AFC258D70988A468000655EE /* laser.xml */, @@ -15048,6 +15268,7 @@ AFC258F40988A469000655EE /* piecewise.xml */, AFC258F50988A469000655EE /* pinion.xml */, AFC258F60988A469000655EE /* pipes.xml */, + AF2D868A2DB1FDB900B4F248 /* platonicfolding.xml */, AFC258F70988A469000655EE /* polyhedra.xml */, AFC258F80988A469000655EE /* polyominoes.xml */, AFC258F90988A469000655EE /* polytopes.xml */, @@ -15145,6 +15366,7 @@ children = ( AFDA11211934424D003D397F /* aligned_malloc.c */, AFDA11221934424D003D397F /* aligned_malloc.h */, + AF5D4E3B2D6409AE009BE57E /* ansi-tty.c */, CE9289D119BD00E200961F22 /* async_netdb.c */, CE9289D219BD00E300961F22 /* async_netdb.h */, AF9D473609B52EE0006E59CF /* colorbars.c */, @@ -15205,6 +15427,8 @@ AFA33BD00B0587EE002B0E7D /* webcollage-helper-cocoa.m */, AFE943AF19DD54C1000A5E6D /* xft.c */, AFE943B019DD54C1000A5E6D /* xft.h */, + AFBD953C2C504ADC000DA52A /* xftwrap.c */, + AFBD953B2C504ADB000DA52A /* xftwrap.h */, AF480CBB098E37D600FB32B8 /* xlockmore.c */, AF480C89098E346700FB32B8 /* xlockmore.h */, AF480C8A098E34AB00FB32B8 /* xlockmoreI.h */, @@ -15536,6 +15760,44 @@ productReference = AF2D0D3A241D7C870001D8B8 /* EtruscanVenus.saver */; productType = "com.apple.product-type.bundle"; }; + AF2D86722DB1FCC900B4F248 /* PlatonicFolding */ = { + isa = PBXNativeTarget; + buildConfigurationList = AF2D86842DB1FCC900B4F248 /* Build configuration list for PBXNativeTarget "PlatonicFolding" */; + buildPhases = ( + AF2D86752DB1FCC900B4F248 /* Resources */, + AF2D86772DB1FCC900B4F248 /* Sources */, + AF2D867B2DB1FCC900B4F248 /* Frameworks */, + AF2D86832DB1FCC900B4F248 /* Run Update Info Plist */, + ); + buildRules = ( + ); + dependencies = ( + AF2D86732DB1FCC900B4F248 /* PBXTargetDependency */, + ); + name = PlatonicFolding; + productName = DangerBall; + productReference = AF2D86872DB1FCC900B4F248 /* PlatonicFolding.saver */; + productType = "com.apple.product-type.bundle"; + }; + AF2D86952DB20F2100B4F248 /* Klondike */ = { + isa = PBXNativeTarget; + buildConfigurationList = AF2D86A62DB20F2100B4F248 /* Build configuration list for PBXNativeTarget "Klondike" */; + buildPhases = ( + AF2D86982DB20F2100B4F248 /* Resources */, + AF2D869A2DB20F2100B4F248 /* Sources */, + AF2D869D2DB20F2100B4F248 /* Frameworks */, + AF2D86A52DB20F2100B4F248 /* Run Update Info Plist */, + ); + buildRules = ( + ); + dependencies = ( + AF2D86962DB20F2100B4F248 /* PBXTargetDependency */, + ); + name = Klondike; + productName = DangerBall; + productReference = AF2D86A92DB20F2100B4F248 /* Klondike.saver */; + productType = "com.apple.product-type.bundle"; + }; AF32D9E00F3AD0B40080F535 /* RubikBlocks */ = { isa = PBXNativeTarget; buildConfigurationList = AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */; @@ -19584,6 +19846,25 @@ productReference = AFA6AB0520999950006D2685 /* GlitchPEG.saver */; productType = "com.apple.product-type.bundle"; }; + AFA82E1D2DB1EB4B00BEEE3E /* HopfFibration */ = { + isa = PBXNativeTarget; + buildConfigurationList = AFA82E2E2DB1EB4B00BEEE3E /* Build configuration list for PBXNativeTarget "HopfFibration" */; + buildPhases = ( + AFA82E202DB1EB4B00BEEE3E /* Resources */, + AFA82E222DB1EB4B00BEEE3E /* Sources */, + AFA82E252DB1EB4B00BEEE3E /* Frameworks */, + AFA82E2D2DB1EB4B00BEEE3E /* Run Update Info Plist */, + ); + buildRules = ( + ); + dependencies = ( + AFA82E1E2DB1EB4B00BEEE3E /* PBXTargetDependency */, + ); + name = HopfFibration; + productName = DangerBall; + productReference = AFA82E312DB1EB4B00BEEE3E /* HopfFibration.saver */; + productType = "com.apple.product-type.bundle"; + }; AFAAE387207D6343007A515C /* Maze3D */ = { isa = PBXNativeTarget; buildConfigurationList = AFAAE399207D6343007A515C /* Build configuration list for PBXNativeTarget "Maze3D" */; @@ -19780,6 +20061,25 @@ productReference = AFC644652AE478FA00D589B9 /* Kallisti.saver */; productType = "com.apple.product-type.bundle"; }; + AFCB48982DBC0958006296D3 /* DumpsterFire */ = { + isa = PBXNativeTarget; + buildConfigurationList = AFCB48A92DBC0958006296D3 /* Build configuration list for PBXNativeTarget "DumpsterFire" */; + buildPhases = ( + AFCB489B2DBC0958006296D3 /* Resources */, + AFCB489D2DBC0958006296D3 /* Sources */, + AFCB48A02DBC0958006296D3 /* Frameworks */, + AFCB48A82DBC0958006296D3 /* Run Update Info Plist */, + ); + buildRules = ( + ); + dependencies = ( + AFCB48992DBC0958006296D3 /* PBXTargetDependency */, + ); + name = DumpsterFire; + productName = DangerBall; + productReference = AFCB48AC2DBC0958006296D3 /* DumpsterFire.saver */; + productType = "com.apple.product-type.bundle"; + }; AFCF833B1AF5B515008BB7E1 /* SplitFlap */ = { isa = PBXNativeTarget; buildConfigurationList = AFCF834D1AF5B515008BB7E1 /* Build configuration list for PBXNativeTarget "SplitFlap" */; @@ -20795,7 +21095,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1500; + LastUpgradeCheck = 1620; TargetAttributes = { AF08398F09930B6B00277BE9 = { DevelopmentTeam = 4627ATJELP; @@ -21852,6 +22152,7 @@ AFF449E02275494400DB8EDB /* DeepStars */, AF39381A1D0FBD6A00205406 /* Discoball */, AF77786109B6536000EA3033 /* DNAlogo */, + AFCB48982DBC0958006296D3 /* DumpsterFire */, AFEC23CD1CB6EAE100DE138F /* DymaxionMap */, AFACE8731CC83458008B24CD /* EnergyStream */, AFA55E0D09935EDC00F3E977 /* Endgame */, @@ -21886,6 +22187,7 @@ AF0BF6CD29456B2E000D9473 /* HexTrail */, AF42CF4E2BE8A3B300675AC7 /* HighVoltage */, AF78D175142DD8F3002AAF77 /* Hilbert */, + AFA82E1D2DB1EB4B00BEEE3E /* HopfFibration */, AFC0E8AB1CDC601A008CAFAC /* Hydrostat */, AFA55F420993629000F3E977 /* Hypertorus */, AF3C71450D624BF50030CC0D /* Hypnowheel */, @@ -21895,6 +22197,7 @@ AF7510FF1782B5B900380EA1 /* Kaleidocycle */, AFC644512AE478FA00D589B9 /* Kallisti */, AFA55F2A0993622F00F3E977 /* Klein */, + AF2D86952DB20F2100B4F248 /* Klondike */, AFA55A790993364300F3E977 /* Lament */, AFA55DC809935D7000F3E977 /* Lavalite */, AF4FD6E60CE7A486005EE58E /* Lockward */, @@ -21915,6 +22218,7 @@ AFD51B1B0F063B4A00471C02 /* Photopile */, AFA5621F0993852500F3E977 /* Pinion */, AF4812B30990D3D900FB32B8 /* Pipes */, + AF2D86722DB1FCC900B4F248 /* PlatonicFolding */, AFA5619D09937D7E00F3E977 /* Polyhedra */, AFA560AE0993718D00F3E977 /* Polytopes */, AFFAB31519158CE40020F021 /* ProjectivePlane */, @@ -22087,6 +22391,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AF2D86752DB1FCC900B4F248 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AF2D868C2DB1FDB900B4F248 /* platonicfolding.xml in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AF2D86982DB20F2100B4F248 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AF2D86B02DB2100A00B4F248 /* klondike.xml in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AF32D9E30F3AD0B40080F535 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -22729,6 +23049,7 @@ AF56892A26E7060500CCBA38 /* distort.xml in Resources */, AF56892B26E7060500CCBA38 /* dnalogo.xml in Resources */, AF7F06172A50C18C00E35B45 /* droste.xml in Resources */, + AFCB48B92DBC0BDB006296D3 /* dumpsterfire.xml in Resources */, AF56892C26E7060500CCBA38 /* dymaxionmap.xml in Resources */, AF56892D26E7060500CCBA38 /* drift.xml in Resources */, AF56892E26E7060500CCBA38 /* endgame.xml in Resources */, @@ -22784,6 +23105,7 @@ AF42CF692BE8A50E00675AC7 /* highvoltage.xml in Resources */, AF56895F26E7060500CCBA38 /* hilbert.xml in Resources */, AF56896026E7060500CCBA38 /* hopalong.xml in Resources */, + AFA82E362DB1EC3B00BEEE3E /* hopffibration.xml in Resources */, AF56896126E7060500CCBA38 /* hydrostat.xml in Resources */, AF56896226E7060500CCBA38 /* hypertorus.xml in Resources */, AF56896326E7060500CCBA38 /* hypnowheel.xml in Resources */, @@ -22800,6 +23122,7 @@ AF56896E26E7060500CCBA38 /* kaleidescope.xml in Resources */, AFC6446F2AE479BC00D589B9 /* kallisti.xml in Resources */, AF56896F26E7060500CCBA38 /* klein.xml in Resources */, + AF2D86B12DB2100A00B4F248 /* klondike.xml in Resources */, AF56897026E7060500CCBA38 /* kumppa.xml in Resources */, AF56897126E7060500CCBA38 /* lament.xml in Resources */, AF56897226E7060500CCBA38 /* lavalite.xml in Resources */, @@ -22836,6 +23159,7 @@ AF56899026E7060500CCBA38 /* piecewise.xml in Resources */, AF56899126E7060500CCBA38 /* pinion.xml in Resources */, AF56899226E7060500CCBA38 /* pipes.xml in Resources */, + AF2D868F2DB1FDB900B4F248 /* platonicfolding.xml in Resources */, AF56899326E7060500CCBA38 /* polyhedra.xml in Resources */, AF56899426E7060500CCBA38 /* polyominoes.xml in Resources */, AF56899526E7060500CCBA38 /* polytopes.xml in Resources */, @@ -23397,6 +23721,7 @@ AF918AE7158FC53D002B5D1E /* distort.xml in Resources */, AFCF453815986A3000E6E8CC /* dnalogo.xml in Resources */, AF7F06162A50C18C00E35B45 /* droste.xml in Resources */, + AFCB48B32DBC0BDB006296D3 /* dumpsterfire.xml in Resources */, AFEC23E81CB6EC6800DE138F /* dymaxionmap.xml in Resources */, AF918AE9158FC53D002B5D1E /* drift.xml in Resources */, AF918AEA158FC53D002B5D1E /* endgame.xml in Resources */, @@ -23452,6 +23777,7 @@ AF42CF682BE8A50E00675AC7 /* highvoltage.xml in Resources */, AF918B14158FC53D002B5D1E /* hilbert.xml in Resources */, AF918B15158FC53D002B5D1E /* hopalong.xml in Resources */, + AFA82E3C2DB1EC3B00BEEE3E /* hopffibration.xml in Resources */, AFC0E8C71CDC60DE008CAFAC /* hydrostat.xml in Resources */, AF918B18158FC53D002B5D1E /* hypertorus.xml in Resources */, AF918B19158FC53D002B5D1E /* hypnowheel.xml in Resources */, @@ -23468,6 +23794,7 @@ AF918B24158FC53D002B5D1E /* kaleidescope.xml in Resources */, AFC6446E2AE479BC00D589B9 /* kallisti.xml in Resources */, AF918B25158FC53D002B5D1E /* klein.xml in Resources */, + AF2D86B42DB2100A00B4F248 /* klondike.xml in Resources */, AF918B26158FC53D002B5D1E /* kumppa.xml in Resources */, AF918B27158FC53D002B5D1E /* lament.xml in Resources */, AF918B29158FC53D002B5D1E /* lavalite.xml in Resources */, @@ -23504,6 +23831,7 @@ AF918B4A158FC53E002B5D1E /* piecewise.xml in Resources */, AF918B4B158FC53E002B5D1E /* pinion.xml in Resources */, AF918B4C158FC53E002B5D1E /* pipes.xml in Resources */, + AF2D868D2DB1FDB900B4F248 /* platonicfolding.xml in Resources */, AFCF4547159878D500E6E8CC /* polyhedra.xml in Resources */, AF918B4E158FC53E002B5D1E /* polyominoes.xml in Resources */, AF918B4F158FC53E002B5D1E /* polytopes.xml in Resources */, @@ -24343,6 +24671,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AFA82E202DB1EB4B00BEEE3E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AFA82E392DB1EC3B00BEEE3E /* hopffibration.xml in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AFAAE38A207D6343007A515C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -24425,6 +24761,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AFCB489B2DBC0958006296D3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AFCB48B42DBC0BDB006296D3 /* dumpsterfire.xml in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AFCF833E1AF5B515008BB7E1 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -25046,6 +25390,40 @@ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; showEnvVarsInLog = 0; }; + AF2D86832DB1FCC900B4F248 /* Run Update Info Plist */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", + ); + name = "Run Update Info Plist"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; + showEnvVarsInLog = 0; + }; + AF2D86A52DB20F2100B4F248 /* Run Update Info Plist */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", + ); + name = "Run Update Info Plist"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX\n"; + showEnvVarsInLog = 0; + }; AF32D9F00F3AD0B40080F535 /* Run Update Info Plist */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -25974,7 +26352,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; + shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX\n"; showEnvVarsInLog = 0; }; AFA3D69409C03B6200E4CFCA /* Run Update Info Plist */ = { @@ -28303,7 +28681,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; + shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX\n"; showEnvVarsInLog = 0; }; AFA3D97309C03DD300E4CFCA /* Run Update Info Plist */ = { @@ -29190,6 +29568,23 @@ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; showEnvVarsInLog = 0; }; + AFA82E2D2DB1EB4B00BEEE3E /* Run Update Info Plist */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", + ); + name = "Run Update Info Plist"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; + showEnvVarsInLog = 0; + }; AFAAE398207D6343007A515C /* Run Update Info Plist */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -29409,6 +29804,23 @@ shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX"; showEnvVarsInLog = 0; }; + AFCB48A82DBC0958006296D3 /* Run Update Info Plist */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", + ); + name = "Run Update Info Plist"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "$SOURCE_ROOT/update-info-plist.pl -q $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX\n"; + showEnvVarsInLog = 0; + }; AFCCCBB509C033DF00353F4D /* Run Update Info Plist */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -30005,6 +30417,25 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AF2D86772DB1FCC900B4F248 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AF2D867A2DB1FCC900B4F248 /* XScreenSaverSubclass.m in Sources */, + AF2D868B2DB1FDB900B4F248 /* platonicfolding.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AF2D869A2DB20F2100B4F248 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AF2D86AE2DB2100A00B4F248 /* klondike.c in Sources */, + AF2D86AF2DB2100A00B4F248 /* klondike-game.c in Sources */, + AF2D869C2DB20F2100B4F248 /* XScreenSaverSubclass.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AF32D9E50F3AD0B40080F535 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -30833,6 +31264,7 @@ AF568A6026E7060500CCBA38 /* wormhole.c in Sources */, AF568A6126E7060500CCBA38 /* xanalogtv.c in Sources */, AF568A6226E7060500CCBA38 /* xflame.c in Sources */, + AF2D86912DB2013200B4F248 /* xftwrap.c in Sources */, AF568A6326E7060500CCBA38 /* xjack.c in Sources */, AF568A6426E7060500CCBA38 /* xlyap.c in Sources */, AF568A6526E7060500CCBA38 /* xmatrix.c in Sources */, @@ -30887,6 +31319,8 @@ AF568A9326E7060500CCBA38 /* deepstars.c in Sources */, AF568A9426E7060500CCBA38 /* dnalogo.c in Sources */, AF568A9526E7060500CCBA38 /* dolphin.c in Sources */, + AFCB48B82DBC0BDB006296D3 /* dumpsterfire.c in Sources */, + AFCB48B72DBC0BDB006296D3 /* dumpster_model.c in Sources */, AF568A9626E7060500CCBA38 /* dymaxionmap.c in Sources */, AF568A0C26E7060500CCBA38 /* dymaxionmap-coords.c in Sources */, AF568A9726E7060500CCBA38 /* dropshadow.c in Sources */, @@ -30927,6 +31361,8 @@ AF42CF6C2BE8A50E00675AC7 /* highvoltage_model.c in Sources */, AF42CF6F2BE8A50E00675AC7 /* highvoltage.c in Sources */, AF568AB926E7060500CCBA38 /* hilbert.c in Sources */, + AFA82E372DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c in Sources */, + AFA82E382DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c in Sources */, AF568ABA26E7060500CCBA38 /* hydrostat.c in Sources */, AF568ABB26E7060500CCBA38 /* hypertorus.c in Sources */, AF568ABC26E7060500CCBA38 /* hypnowheel.c in Sources */, @@ -30938,6 +31374,8 @@ AFC644722AE479BC00D589B9 /* kallisti.c in Sources */, AFC6446C2AE479BC00D589B9 /* kallisti_model.c in Sources */, AF568AC226E7060500CCBA38 /* klein.c in Sources */, + AF2D86B22DB2100A00B4F248 /* klondike.c in Sources */, + AF2D86B32DB2100A00B4F248 /* klondike-game.c in Sources */, AF568AC326E7060500CCBA38 /* lament.c in Sources */, AF568AC426E7060500CCBA38 /* lament_model.c in Sources */, AF568AC526E7060500CCBA38 /* lavalite.c in Sources */, @@ -30959,6 +31397,7 @@ AF568AD426E7060500CCBA38 /* pinion.c in Sources */, AF568AD526E7060500CCBA38 /* pipeobjs.c in Sources */, AF568AD626E7060500CCBA38 /* pipes.c in Sources */, + AF2D86902DB1FDB900B4F248 /* platonicfolding.c in Sources */, AF568AD726E7060500CCBA38 /* polyhedra-gl.c in Sources */, AF568AD826E7060500CCBA38 /* polyhedra.c in Sources */, AF568AD926E7060500CCBA38 /* polytopes.c in Sources */, @@ -31020,6 +31459,7 @@ AF568B0A26E7060500CCBA38 /* toast2.c in Sources */, AF568B0B26E7060500CCBA38 /* toaster.c in Sources */, AF568B0C26E7060500CCBA38 /* toaster_base.c in Sources */, + AF5D4E3E2D6409AE009BE57E /* ansi-tty.c in Sources */, AF568B0D26E7060500CCBA38 /* toaster_handle.c in Sources */, AF568B0E26E7060500CCBA38 /* toaster_handle2.c in Sources */, AF568B0F26E7060500CCBA38 /* toaster_jet.c in Sources */, @@ -31309,6 +31749,7 @@ files = ( AF7776EA09B63ABF00EA3033 /* XScreenSaverSubclass.m in Sources */, AF77770409B63B5F00EA3033 /* phosphor.c in Sources */, + AF5D4E3C2D6409AE009BE57E /* ansi-tty.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -31633,6 +32074,7 @@ AF9189F5158FC35E002B5D1E /* wormhole.c in Sources */, AF9189F6158FC35E002B5D1E /* xanalogtv.c in Sources */, AF9189F7158FC35E002B5D1E /* xflame.c in Sources */, + AF2D86922DB2014100B4F248 /* xftwrap.c in Sources */, AF9189F8158FC35E002B5D1E /* xjack.c in Sources */, AF9189F9158FC35E002B5D1E /* xlyap.c in Sources */, AF9189FA158FC35E002B5D1E /* xmatrix.c in Sources */, @@ -31687,6 +32129,8 @@ AF2C2A8A22754C31002112B9 /* deepstars.c in Sources */, AFCF453715986A2100E6E8CC /* dnalogo.c in Sources */, AF918A48158FC3BB002B5D1E /* dolphin.c in Sources */, + AFCB48B22DBC0BDB006296D3 /* dumpsterfire.c in Sources */, + AFCB48B12DBC0BDB006296D3 /* dumpster_model.c in Sources */, AFEC23E91CB6EC7F00DE138F /* dymaxionmap.c in Sources */, AF4C300F208569AA00BE1DEF /* dymaxionmap-coords.c in Sources */, AF918A49158FC3BB002B5D1E /* dropshadow.c in Sources */, @@ -31722,11 +32166,13 @@ AF62D6342180082100C57C42 /* handsy.c in Sources */, AF96015D25759124007FA31B /* headroom.c in Sources */, AF96015B25759124007FA31B /* headroom_model.c in Sources */, - AF42CF6E2BE8A50E00675AC7 /* highvoltage.c in Sources */, AF1B0FC31D7AB5500011DBE4 /* hexstrut.c in Sources */, AF0BF6E829456CCC000D9473 /* hextrail.c in Sources */, + AF42CF6E2BE8A50E00675AC7 /* highvoltage.c in Sources */, AF42CF6B2BE8A50E00675AC7 /* highvoltage_model.c in Sources */, AF918A6A158FC3E5002B5D1E /* hilbert.c in Sources */, + AFA82E3D2DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c in Sources */, + AFA82E3E2DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c in Sources */, AFC0E8C41CDC60B0008CAFAC /* hydrostat.c in Sources */, AF918A6B158FC3E5002B5D1E /* hypertorus.c in Sources */, AF918A6C158FC3E5002B5D1E /* hypnowheel.c in Sources */, @@ -31738,6 +32184,8 @@ AFC644712AE479BC00D589B9 /* kallisti.c in Sources */, AFC6446B2AE479BC00D589B9 /* kallisti_model.c in Sources */, AF918A70158FC417002B5D1E /* klein.c in Sources */, + AF2D86B52DB2100A00B4F248 /* klondike.c in Sources */, + AF2D86B62DB2100A00B4F248 /* klondike-game.c in Sources */, AF918A71158FC417002B5D1E /* lament.c in Sources */, AFF1BA1019A96D8B0016A88D /* lament_model.c in Sources */, AF918A72158FC417002B5D1E /* lavalite.c in Sources */, @@ -31759,6 +32207,7 @@ AF918A7D158FC417002B5D1E /* pinion.c in Sources */, AF918A7E158FC417002B5D1E /* pipeobjs.c in Sources */, AF918A7F158FC417002B5D1E /* pipes.c in Sources */, + AF2D868E2DB1FDB900B4F248 /* platonicfolding.c in Sources */, AFCF4545159878C300E6E8CC /* polyhedra-gl.c in Sources */, AFCF4546159878C300E6E8CC /* polyhedra.c in Sources */, AF918A82158FC417002B5D1E /* polytopes.c in Sources */, @@ -31820,6 +32269,7 @@ AF918AA7158FC473002B5D1E /* toast2.c in Sources */, AF918AA8158FC473002B5D1E /* toaster.c in Sources */, AF918AA9158FC473002B5D1E /* toaster_base.c in Sources */, + AF5D4E3D2D6409AE009BE57E /* ansi-tty.c in Sources */, AF918AAA158FC473002B5D1E /* toaster_handle.c in Sources */, AF918AAB158FC473002B5D1E /* toaster_handle2.c in Sources */, AF918AAC158FC473002B5D1E /* toaster_jet.c in Sources */, @@ -32152,6 +32602,7 @@ AF9D4DB609B5B71E006E59CF /* analogtv.c in Sources */, AF9D4DC409B5B87D006E59CF /* bsod.c in Sources */, AF9D4DD409B5B990006E59CF /* apple2.c in Sources */, + AFBD953D2C504AFC000DA52A /* xftwrap.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -32160,6 +32611,7 @@ buildActionMask = 2147483647; files = ( AF9D4DF209B5BB19006E59CF /* XScreenSaverSubclass.m in Sources */, + AF5D4E3F2D6409AE009BE57E /* ansi-tty.c in Sources */, AF9D4DF309B5BB19006E59CF /* analogtv.c in Sources */, AF9D4DF509B5BB19006E59CF /* apple2.c in Sources */, AF9D4E0609B5BC9D006E59CF /* apple2-main.c in Sources */, @@ -32725,6 +33177,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AFA82E222DB1EB4B00BEEE3E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AFA82E3A2DB1EC3B00BEEE3E /* hacks/glx/hopffibration.c in Sources */, + AFA82E3B2DB1EC3B00BEEE3E /* hacks/glx/hopfanimations.c in Sources */, + AFA82E242DB1EB4B00BEEE3E /* XScreenSaverSubclass.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AFAAE38C207D6343007A515C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -32821,6 +33283,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AFCB489D2DBC0958006296D3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AFCB48B52DBC0BDB006296D3 /* dumpster_model.c in Sources */, + AFCB48B62DBC0BDB006296D3 /* dumpsterfire.c in Sources */, + AFCB489F2DBC0958006296D3 /* XScreenSaverSubclass.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; AFCF83401AF5B515008BB7E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -33494,6 +33966,26 @@ target = AF2D0D25241D7C870001D8B8 /* EtruscanVenus */; targetProxy = AF2D0D42241D7D9F0001D8B8 /* PBXContainerItemProxy */; }; + AF2D86732DB1FCC900B4F248 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; + targetProxy = AF2D86742DB1FCC900B4F248 /* PBXContainerItemProxy */; + }; + AF2D86942DB2032D00B4F248 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AF2D86722DB1FCC900B4F248 /* PlatonicFolding */; + targetProxy = AF2D86932DB2032D00B4F248 /* PBXContainerItemProxy */; + }; + AF2D86962DB20F2100B4F248 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; + targetProxy = AF2D86972DB20F2100B4F248 /* PBXContainerItemProxy */; + }; + AF2D86B82DB2105300B4F248 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AF2D86952DB20F2100B4F248 /* Klondike */; + targetProxy = AF2D86B72DB2105300B4F248 /* PBXContainerItemProxy */; + }; AF32D9E10F3AD0B40080F535 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; @@ -35749,6 +36241,16 @@ target = AFA6AAF020999950006D2685 /* GlitchPEG */; targetProxy = AFA6AB1020999A9A006D2685 /* PBXContainerItemProxy */; }; + AFA82E1E2DB1EB4B00BEEE3E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; + targetProxy = AFA82E1F2DB1EB4B00BEEE3E /* PBXContainerItemProxy */; + }; + AFA82E402DB1ECC600BEEE3E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AFA82E1D2DB1EB4B00BEEE3E /* HopfFibration */; + targetProxy = AFA82E3F2DB1ECC600BEEE3E /* PBXContainerItemProxy */; + }; AFAAE388207D6343007A515C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; @@ -35889,6 +36391,16 @@ target = AF9771D60989DC4A001F8B92 /* SaverTester */; targetProxy = AFCAD5F80992DFE00009617A /* PBXContainerItemProxy */; }; + AFCB48992DBC0958006296D3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; + targetProxy = AFCB489A2DBC0958006296D3 /* PBXContainerItemProxy */; + }; + AFCB48BB2DBC0C3E006296D3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = AFCB48982DBC0958006296D3 /* DumpsterFire */; + targetProxy = AFCB48BA2DBC0C3E006296D3 /* PBXContainerItemProxy */; + }; AFCF833C1AF5B515008BB7E1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AF4808C0098C3B6C00FB32B8 /* jwxyz */; @@ -36541,6 +37053,50 @@ }; name = Release; }; + AF2D86852DB1FCC900B4F248 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + AF2D86862DB1FCC900B4F248 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + AF2D86A72DB20F2100B4F248 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + AF2D86A82DB20F2100B4F248 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; AF32D9F20F3AD0B40080F535 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -40225,6 +40781,28 @@ }; name = Release; }; + AFA82E2F2DB1EB4B00BEEE3E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + AFA82E302DB1EB4B00BEEE3E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; AFAAE39A207D6343007A515C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -40451,6 +41029,28 @@ }; name = Release; }; + AFCB48AA2DBC0958006296D3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + AFCB48AB2DBC0958006296D3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + "USE_GL=1", + "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; AFCF834E1AF5B515008BB7E1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -41583,6 +42183,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + AF2D86842DB1FCC900B4F248 /* Build configuration list for PBXNativeTarget "PlatonicFolding" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AF2D86852DB1FCC900B4F248 /* Debug */, + AF2D86862DB1FCC900B4F248 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AF2D86A62DB20F2100B4F248 /* Build configuration list for PBXNativeTarget "Klondike" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AF2D86A72DB20F2100B4F248 /* Debug */, + AF2D86A82DB20F2100B4F248 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; AF32D9F10F3AD0B40080F535 /* Build configuration list for PBXNativeTarget "RubikBlocks" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -43554,6 +44172,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + AFA82E2E2DB1EB4B00BEEE3E /* Build configuration list for PBXNativeTarget "HopfFibration" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AFA82E2F2DB1EB4B00BEEE3E /* Debug */, + AFA82E302DB1EB4B00BEEE3E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; AFAAE399207D6343007A515C /* Build configuration list for PBXNativeTarget "Maze3D" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -43653,6 +44280,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + AFCB48A92DBC0958006296D3 /* Build configuration list for PBXNativeTarget "DumpsterFire" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AFCB48AA2DBC0958006296D3 /* Debug */, + AFCB48AB2DBC0958006296D3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; AFCF834D1AF5B515008BB7E1 /* Build configuration list for PBXNativeTarget "SplitFlap" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Abstractile.xcscheme b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Abstractile.xcscheme index 21949a56..e3c0158e 100644 --- a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Abstractile.xcscheme +++ b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Abstractile.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/DymaxionMap.xcscheme b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/DymaxionMap.xcscheme index 0db594b3..c5a54d21 100644 --- a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/DymaxionMap.xcscheme +++ b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/DymaxionMap.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Hydrostat.xcscheme b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Hydrostat.xcscheme index 514ac239..c81eb7ca 100644 --- a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Hydrostat.xcscheme +++ b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Hydrostat.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Kumppa.xcscheme b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Kumppa.xcscheme index 16b59815..dd3baae1 100644 --- a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Kumppa.xcscheme +++ b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Kumppa.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Polyhedra.xcscheme b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Polyhedra.xcscheme index cd9ae25e..792e885e 100644 --- a/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Polyhedra.xcscheme +++ b/OSX/xscreensaver.xcodeproj/xcshareddata/xcschemes/Polyhedra.xcscheme @@ -1,6 +1,6 @@ = 33) { + permission = Manifest.permission.READ_MEDIA_IMAGES; + } else { + permission = Manifest.permission.READ_EXTERNAL_STORAGE; + } if (permissionGranted(permission)) { withProceed(); } else { diff --git a/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java b/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java index 889040a4..b9eb7dd9 100644 --- a/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java +++ b/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java @@ -1,5 +1,5 @@ /* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * xscreensaver, Copyright © 2016-2021 Jamie Zawinski + * xscreensaver, Copyright © 2016-2024 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -38,6 +38,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.net.Uri; +import android.os.Build; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; @@ -666,8 +667,13 @@ public class jwxyz public Object[] checkThenLoadRandomImage (int target_width, int target_height, boolean rotate_p) { - // RES introduced in API 16 - String permission = Manifest.permission.READ_EXTERNAL_STORAGE; + + String permission = ""; + if (Build.VERSION.SDK_INT >= 33) { + permission = Manifest.permission.READ_MEDIA_IMAGES; + } else { + permission = Manifest.permission.READ_EXTERNAL_STORAGE; + } if (havePermission(permission)) { return loadRandomImage(target_width,target_height,rotate_p); diff --git a/configure b/configure index 5bba409a..af5e09ee 100755 --- a/configure +++ b/configure @@ -20150,6 +20150,18 @@ have_swresample="$ok" # Check includes if test "$have_avutil" = yes; then ac_save_avutil_CPPFLAGS="$CPPFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libavutil includes" >&5 +printf %s "checking for libavutil includes... " >&6; } +if test ${ac_cv_avutil_config_cflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_avutil_config_cflags=`$pkg_config --cflags libavutil` ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_avutil_config_cflags" >&5 +printf "%s\n" "$ac_cv_avutil_config_cflags" >&6; } + ac_avutil_config_cflags=$ac_cv_avutil_config_cflags CPPFLAGS="$CPPFLAGS $ac_avutil_config_cflags" have_avutil=no @@ -20171,6 +20183,18 @@ fi if test "$have_avcodec" = yes; then ac_save_avcodec_CPPFLAGS="$CPPFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libavcodec includes" >&5 +printf %s "checking for libavcodec includes... " >&6; } +if test ${ac_cv_avcodec_config_cflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_avcodec_config_cflags=`$pkg_config --cflags libavcodec` ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_avcodec_config_cflags" >&5 +printf "%s\n" "$ac_cv_avcodec_config_cflags" >&6; } + ac_avcodec_config_cflags=$ac_cv_avcodec_config_cflags CPPFLAGS="$CPPFLAGS $ac_avcodec_config_cflags" have_avcodec=no @@ -20192,6 +20216,18 @@ fi if test "$have_avformat" = yes; then ac_save_avformat_CPPFLAGS="$CPPFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libavformat includes" >&5 +printf %s "checking for libavformat includes... " >&6; } +if test ${ac_cv_avformat_config_cflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_avformat_config_cflags=`$pkg_config --cflags libavformat` ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_avformat_config_cflags" >&5 +printf "%s\n" "$ac_cv_avformat_config_cflags" >&6; } + ac_avformat_config_cflags=$ac_cv_avformat_config_cflags CPPFLAGS="$CPPFLAGS $ac_avformat_config_cflags" have_avformat=no @@ -20213,6 +20249,18 @@ fi if test "$have_swscale" = yes; then ac_save_swscale_CPPFLAGS="$CPPFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libswscale includes" >&5 +printf %s "checking for libswscale includes... " >&6; } +if test ${ac_cv_swscale_config_cflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_swscale_config_cflags=`$pkg_config --cflags libswscale` ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_swscale_config_cflags" >&5 +printf "%s\n" "$ac_cv_swscale_config_cflags" >&6; } + ac_swscale_config_cflags=$ac_cv_swscale_config_cflags CPPFLAGS="$CPPFLAGS $ac_swscale_config_cflags" have_swscale=no @@ -20234,6 +20282,18 @@ fi if test "$have_swresample" = yes; then ac_save_swresample_CPPFLAGS="$CPPFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libswresample includes" >&5 +printf %s "checking for libswresample includes... " >&6; } +if test ${ac_cv_swresample_config_cflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_swresample_config_cflags=`$pkg_config --cflags libswresample` ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_swresample_config_cflags" >&5 +printf "%s\n" "$ac_cv_swresample_config_cflags" >&6; } + ac_swresample_config_cflags=$ac_cv_swresample_config_cflags CPPFLAGS="$CPPFLAGS $ac_swresample_config_cflags" have_swresample=no @@ -20658,17 +20718,6 @@ if test "$have_avformat" = yes -a \ "$have_swscale" = yes -a \ "$have_swresample" = yes ; then have_ffmpeg=yes - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffmpeg includes" >&5 -printf %s "checking for ffmpeg includes... " >&6; } -if test ${ac_cv_ffmpeg_config_cflags+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) ac_cv_ffmpeg_config_cflags=`$pkg_config --cflags $pkgs` ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ffmpeg_config_cflags" >&5 -printf "%s\n" "$ac_cv_ffmpeg_config_cflags" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffmpeg libs" >&5 printf %s "checking for ffmpeg libs... " >&6; } if test ${ac_cv_ffmpeg_config_libs+y} @@ -20684,7 +20733,13 @@ printf "%s\n" "$ac_cv_ffmpeg_config_libs" >&6; } FFMPEG_OBJS='$(FFMPEG_OBJS)' fi -ac_ffmpeg_config_cflags=$ac_cv_ffmpeg_config_cflags +ac_ffmpeg_config_cflags=" \ + $ac_avutil_config_cflags \ + $ac_avcodec_config_cflags \ + $ac_avformat_config_cflags \ + $ac_swscale_config_cflags \ + $ac_swresample_config_cflags \ +" ac_ffmpeg_config_libs=$ac_cv_ffmpeg_config_libs FFMPEG_CFLAGS="$ac_ffmpeg_config_cflags" FFMPEG_LIBS="$ac_ffmpeg_config_libs" diff --git a/configure.ac b/configure.ac index dc2ad2f5..5e847061 100644 --- a/configure.ac +++ b/configure.ac @@ -4015,6 +4015,9 @@ have_swresample="$ok" # Check includes if test "$have_avutil" = yes; then ac_save_avutil_CPPFLAGS="$CPPFLAGS" + AC_CACHE_CHECK([for libavutil includes], ac_cv_avutil_config_cflags, + [ac_cv_avutil_config_cflags=`$pkg_config --cflags libavutil`]) + ac_avutil_config_cflags=$ac_cv_avutil_config_cflags CPPFLAGS="$CPPFLAGS $ac_avutil_config_cflags" have_avutil=no AC_CHECK_X_HEADER(libavutil/avutil.h, [have_avutil=yes]) @@ -4023,6 +4026,9 @@ fi if test "$have_avcodec" = yes; then ac_save_avcodec_CPPFLAGS="$CPPFLAGS" + AC_CACHE_CHECK([for libavcodec includes], ac_cv_avcodec_config_cflags, + [ac_cv_avcodec_config_cflags=`$pkg_config --cflags libavcodec`]) + ac_avcodec_config_cflags=$ac_cv_avcodec_config_cflags CPPFLAGS="$CPPFLAGS $ac_avcodec_config_cflags" have_avcodec=no AC_CHECK_X_HEADER(libavcodec/avcodec.h, [have_avcodec=yes]) @@ -4031,6 +4037,9 @@ fi if test "$have_avformat" = yes; then ac_save_avformat_CPPFLAGS="$CPPFLAGS" + AC_CACHE_CHECK([for libavformat includes], ac_cv_avformat_config_cflags, + [ac_cv_avformat_config_cflags=`$pkg_config --cflags libavformat`]) + ac_avformat_config_cflags=$ac_cv_avformat_config_cflags CPPFLAGS="$CPPFLAGS $ac_avformat_config_cflags" have_avformat=no AC_CHECK_X_HEADER(libavformat/avformat.h, [have_avformat=yes]) @@ -4039,6 +4048,9 @@ fi if test "$have_swscale" = yes; then ac_save_swscale_CPPFLAGS="$CPPFLAGS" + AC_CACHE_CHECK([for libswscale includes], ac_cv_swscale_config_cflags, + [ac_cv_swscale_config_cflags=`$pkg_config --cflags libswscale`]) + ac_swscale_config_cflags=$ac_cv_swscale_config_cflags CPPFLAGS="$CPPFLAGS $ac_swscale_config_cflags" have_swscale=no AC_CHECK_X_HEADER(libswscale/swscale.h, [have_swscale=yes]) @@ -4047,6 +4059,9 @@ fi if test "$have_swresample" = yes; then ac_save_swresample_CPPFLAGS="$CPPFLAGS" + AC_CACHE_CHECK([for libswresample includes], ac_cv_swresample_config_cflags, + [ac_cv_swresample_config_cflags=`$pkg_config --cflags libswresample`]) + ac_swresample_config_cflags=$ac_cv_swresample_config_cflags CPPFLAGS="$CPPFLAGS $ac_swresample_config_cflags" have_swresample=no AC_CHECK_X_HEADER(libswresample/swresample.h, [have_swresample=yes]) @@ -4114,14 +4129,18 @@ if test "$have_avformat" = yes -a \ "$have_swscale" = yes -a \ "$have_swresample" = yes ; then have_ffmpeg=yes - AC_CACHE_CHECK([for ffmpeg includes], ac_cv_ffmpeg_config_cflags, - [ac_cv_ffmpeg_config_cflags=`$pkg_config --cflags $pkgs`]) AC_CACHE_CHECK([for ffmpeg libs], ac_cv_ffmpeg_config_libs, [ac_cv_ffmpeg_config_libs=`$pkg_config --libs $pkgs`]) AC_DEFINE(HAVE_FFMPEG) FFMPEG_OBJS='$(FFMPEG_OBJS)' fi -ac_ffmpeg_config_cflags=$ac_cv_ffmpeg_config_cflags +ac_ffmpeg_config_cflags=" \ + $ac_avutil_config_cflags \ + $ac_avcodec_config_cflags \ + $ac_avformat_config_cflags \ + $ac_swscale_config_cflags \ + $ac_swresample_config_cflags \ +" ac_ffmpeg_config_libs=$ac_cv_ffmpeg_config_libs FFMPEG_CFLAGS="$ac_ffmpeg_config_cflags" FFMPEG_LIBS="$ac_ffmpeg_config_libs" diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index d3e89f5b..eca70448 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -4,8 +4,8 @@ ! a screen saver and locker for the X window system ! by Jamie Zawinski ! -! version 6.09 -! 07-Jun-2024 +! version 6.10 +! 27-Apr-2025 ! ! See "man xscreensaver" for more info. The latest version is always ! available at https://www.jwz.org/xscreensaver/ @@ -577,7 +577,11 @@ XScreenSaver.bourneShell: /bin/sh @GL_KLUDGE@ GL: papercube --root \n\ @GL_KLUDGE@ GL: skulloop --root \n\ @GL_KLUDGE@ GL: highvoltage --root \n\ -@GL_KLUDGE@ GL: kallisti --root \n +@GL_KLUDGE@ GL: kallisti --root \n\ +@GL_KLUDGE@ GL: klondike --root \n\ +@GL_KLUDGE@ GL: dumpsterfire --root \n\ +@GL_KLUDGE@ GL: hopffibration --root \n\ +@GL_KLUDGE@ GL: platonicfolding --root \n @@ -618,6 +622,7 @@ XScreenSaver.bourneShell: /bin/sh *hacks.decayscreen.name: Decay Screen *hacks.deepstars.name: Deep Stars *hacks.dnalogo.name: DNA Logo +*hacks.dumpsterfire.name: Dumpster Fire *hacks.dymaxionmap.name: Dymaxion Map *hacks.energystream.name: Energy Stream *hacks.etruscanvenus.name: Etruscan Venus @@ -651,6 +656,7 @@ XScreenSaver.bourneShell: /bin/sh *hacks.hexstrut.name: Hex Strut *hacks.hextrail.name: Hex Trail *hacks.highvoltage.name: High Voltage +*hacks.hopffibration.name: Hopf Fibration *hacks.ifs.name: IFS *hacks.imsmap.name: IMS Map *hacks.jigglypuff.name: Jiggly Puff @@ -673,6 +679,7 @@ XScreenSaver.bourneShell: /bin/sh *hacks.pacman.name: Pac-Man *hacks.papercube.name: Paper Cube *hacks.photopile.name: Photo Pile +*hacks.platonicfolding.name:Platonic Folding *hacks.popsquares.name: Pop Squares *hacks.projectiveplane.name:Projective Plane *hacks.quasicrystal.name: Quasi-Crystal diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h index c469a3ef..420a474a 100644 --- a/driver/XScreenSaver_ad.h +++ b/driver/XScreenSaver_ad.h @@ -431,7 +431,11 @@ GL: papercube --root \\n\ GL: skulloop --root \\n\ GL: highvoltage --root \\n\ - GL: kallisti --root \\n", + GL: kallisti --root \\n\ + GL: klondike --root \\n\ + GL: dumpsterfire --root \\n\ + GL: hopffibration --root \\n\ + GL: platonicfolding --root \\n", "*hacks.antinspect.name: Ant Inspect", "*hacks.antmaze.name: Ant Maze", "*hacks.antspotlight.name: Ant Spotlight", @@ -462,6 +466,7 @@ "*hacks.decayscreen.name: Decay Screen", "*hacks.deepstars.name: Deep Stars", "*hacks.dnalogo.name: DNA Logo", +"*hacks.dumpsterfire.name: Dumpster Fire", "*hacks.dymaxionmap.name: Dymaxion Map", "*hacks.energystream.name: Energy Stream", "*hacks.etruscanvenus.name: Etruscan Venus", @@ -495,6 +500,7 @@ "*hacks.hexstrut.name: Hex Strut", "*hacks.hextrail.name: Hex Trail", "*hacks.highvoltage.name: High Voltage", +"*hacks.hopffibration.name: Hopf Fibration", "*hacks.ifs.name: IFS", "*hacks.imsmap.name: IMS Map", "*hacks.jigglypuff.name: Jiggly Puff", @@ -517,6 +523,7 @@ "*hacks.pacman.name: Pac-Man", "*hacks.papercube.name: Paper Cube", "*hacks.photopile.name: Photo Pile", +"*hacks.platonicfolding.name:Platonic Folding", "*hacks.popsquares.name: Pop Squares", "*hacks.projectiveplane.name:Projective Plane", "*hacks.quasicrystal.name: Quasi-Crystal", diff --git a/driver/auth.h b/driver/auth.h index 80a49bae..6580502d 100644 --- a/driver/auth.h +++ b/driver/auth.h @@ -1,5 +1,5 @@ /* auth.h --- Providing authentication mechanisms. - * Copyright © 1993-2022 Jamie Zawinski + * Copyright © 1993-2024 Jamie Zawinski * (c) 2007, Quest Software, Inc. All rights reserved. * This file is part of XScreenSaver. * @@ -86,6 +86,7 @@ extern Bool xscreensaver_auth_conv (void *closure, auth_response **resp); extern void xscreensaver_auth_finished (void *closure, Bool authenticated_p); extern void xscreensaver_splash (void *root_widget, Bool disable_settings_p); +extern void xscreensaver_auth_test_mode (void); /* for test-passwd.c */ #endif /* __XSCREENSAVER_AUTH_H__ */ diff --git a/driver/dialog.c b/driver/dialog.c index 417f862f..5b5e868b 100644 --- a/driver/dialog.c +++ b/driver/dialog.c @@ -2337,6 +2337,19 @@ thermo_timer (XtPointer closure, XtIntervalId *id) } +/* This is horrible, but if we don't ignore XInput events when running + test-passwd.c, then every mouse is delivered twice (both XI and Xlib) + so we only see every other page, because every click is a double-click. + Only test_auth_conv() calls this to set this flag. + */ +static Bool test_mode_ignore_xi_events = False; +void +xscreensaver_auth_test_mode (void) +{ + test_mode_ignore_xi_events = True; +} + + static void gui_main_loop (window_state *ws, Bool splash_p, Bool notification_p) { @@ -2422,6 +2435,8 @@ gui_main_loop (window_state *ws, Bool splash_p, Bool notification_p) Bool ok = xinput_event_to_xlib (xev.xcookie.evtype, xev.xcookie.data, &ev2); XFreeEventData (ws->dpy, &xev.xcookie); + if (test_mode_ignore_xi_events) + ok = False; if (ok) xev = ev2; } diff --git a/driver/test-passwd.c b/driver/test-passwd.c index 2c894ac1..8714de6a 100644 --- a/driver/test-passwd.c +++ b/driver/test-passwd.c @@ -34,6 +34,8 @@ test_auth_conv (void *closure, nmsgs = 0; msg = (auth_message *) calloc (100, sizeof(*msg)); + xscreensaver_auth_test_mode(); + # define DIALOG() \ fprintf (stderr, "\n%s: page %d\n", blurb(), page++); \ xscreensaver_auth_conv (closure, nmsgs, msg, resp); \ @@ -93,7 +95,8 @@ test_auth_conv (void *closure, msg[nmsgs].type = AUTH_MSGTYPE_PROMPT_ECHO; - msg[nmsgs].msg = "1/1 Page Five visible text"; + msg[nmsgs].msg = "1/1 Page Five visible text" + "over several lines, probably like three or four; y and g."; nmsgs++; msg[nmsgs].type = AUTH_MSGTYPE_PROMPT_ECHO; diff --git a/driver/xscreensaver-settings.man b/driver/xscreensaver-settings.man index 6ecaa902..d6c5231f 100644 --- a/driver/xscreensaver-settings.man +++ b/driver/xscreensaver-settings.man @@ -307,10 +307,10 @@ file, or it won't work. to get the default host and display number. .TP 8 .B PATH -to find the sub-programs to run. However, note that the sub-programs -actually launched by \fIxscreensaver-settings\fP for display in the -inline preview pane, but are launched by the \fIxscreensaver\fP daemon -when run full screen, so the \fB$PATH\fP setting in both processes matters. +to find the sub-programs to run. However, note that the sub-programs are +launched by \fIxscreensaver-settings\fP for display in the inline preview +pane, but by the \fIxscreensaver\fP daemon when run full screen, so the +\fB$PATH\fP setting in both processes matters. .TP 8 .B HOME for the directory in which to read and write the \fI.xscreensaver\fP file. diff --git a/driver/xscreensaver-systemd.c b/driver/xscreensaver-systemd.c index 2e174b24..e58825f1 100644 --- a/driver/xscreensaver-systemd.c +++ b/driver/xscreensaver-systemd.c @@ -25,12 +25,12 @@ * - When the system is about to go to sleep (e.g., laptop lid closing) * it locks the screen *before* the system goes to sleep, by running * "xscreensaver-command -suspend". And then when the system wakes - * up again, it runs "xscreensaver-command -deactivate" to force the + * up again, it runs "xscreensaver-command --deactivate" to force the * unlock dialog to appear immediately. * * - When another process on the system asks for the screen saver to be * inhibited (e.g. because a video is playing) this program periodically - * runs "xscreensaver-command -deactivate" to keep the display un-blanked. + * runs "xscreensaver-command --deactivate" to keep the display un-blanked. * It does this until the other program asks for it to stop. * * For this to work at all, you must either: @@ -38,7 +38,7 @@ * A: Be running GNOME's "org.gnome.SessionManager" D-Bus service; or * B: Be running KDE's "org.kde.Solid.PowerManagement.PolicyAgent" svc; or * C: Prevent your desktop environment from running the - * "org.freedesktop.ScreenSaver "service. + * "org.freedesktop.ScreenSaver" service. * * ***************************************************************************** @@ -47,7 +47,7 @@ * * For decades, the traditional way for a video player to temporarily * inhibit the screen saver was to have a heartbeat command that ran - * "xscreensaver-command -deactivate" once a minute while the video was + * "xscreensaver-command --deactivate" once a minute while the video was * playing, and ceased when the video was paused or stopped. The reason * to do it as a heartbeat rather than a toggle is so that the player * fails SAFE -- if the player exits abnormally, the heart stops beating, @@ -84,7 +84,7 @@ * * To recap: because the existing video players decided to delete the * single line of code that they already had -- the heartbeat call to - * "xscreensaver-command -deactivate" -- we had to respond by adding + * "xscreensaver-command --deactivate" -- we had to respond by adding * TWELVE HUNDRED LINES of complicated code that talks to a server that * may not be running, and that may not allow us to connect, and that may * not work properly anyway. @@ -145,20 +145,22 @@ * Bad Chromium bug #1: * * It inhibits when only audio is playing, and does so with the same - * message as for audio, so we can't tell them apart. This means that, + * message as for video, so we can't tell them apart. This means that, * unlike Firefox, playing audio-only in Chromium will prevent your * screen from blanking. * * Bad Chromium bug #2: * * It inhibits when short looping videos are playing. Many sites - * (including Twitter) auto-convert GIFs to looping MP4s to save - * bandwidth, so Chromium will inhibit any time such a GIF is visible. + * auto-convert GIFs to looping MP4s to save bandwidth, so Chromium will + * inhibit any time such a GIF is visible. * * The proper way for Chrome to fix this would be to stop inhibiting once * the video loops. That way your multi-hour movie inhibits properly, but - * your looping GIF only inhibits for the first few seconds. - * + * your looping GIF only inhibits for the first few seconds. Other + * reasonable choices might include: do not inhibit for silent or muted + * videos; only inhibit for full-screen videos. + * * ***************************************************************************** * @@ -244,7 +246,7 @@ * I have not verified this: * * ~/.mplayer/config: - * heartbeat-cmd="xscreensaver-command -deactivate >&- 2>&- &" + * heartbeat-cmd="xscreensaver-command --deactivate >&- 2>&- &" * * ***************************************************************************** @@ -271,7 +273,7 @@ * * This setting prevents the screen from blanking, and has a long history * of becoming turned on accidentally. Tries org.freedesktop.ScreenSaver - * and others before falling back to "xscreensaver-command -deactivate" + * and others before falling back to "xscreensaver-command --deactivate" * as a heartbeat. * * @@ -293,8 +295,6 @@ * "org.gnome.SessionManager" with the same behavior, we should probably * listen to "InhibitorAdded" on that as well. * - * - Run under valgrind to check for any memory leaks. - * * - Apparently the two different desktops have managed to come up with * *three* different ways for dbus clients to ask the question, "is the * screen currently blanked?" We should probably also respond to these: @@ -327,8 +327,6 @@ * /ScreenSaver org.freedesktop.ScreenSaver \ * UnInhibit u 1792821391 * - * https://github.com/mato/xscreensaver-systemd - * * ***************************************************************************** */ @@ -464,7 +462,7 @@ xscreensaver_command (const char *cmd) { char buf[1024]; int rc; - sprintf (buf, "xscreensaver-command %.100s -%.100s", + sprintf (buf, "xscreensaver-command %.100s --%.100s", (verbose_p ? "--verbose" : "--quiet"), cmd); if (verbose_p) diff --git a/hacks/Makefile.in b/hacks/Makefile.in index 44b745e0..743073ee 100644 --- a/hacks/Makefile.in +++ b/hacks/Makefile.in @@ -1,4 +1,4 @@ -# hacks/Makefile.in --- xscreensaver, Copyright © 1997-2024 Jamie Zawinski. +# hacks/Makefile.in --- xscreensaver, Copyright © 1997-2025 Jamie Zawinski. # the `../configure' script generates `hacks/Makefile' from this file. @SET_MAKE@ @@ -51,6 +51,8 @@ X_PRE_LIBS = @X_PRE_LIBS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ XFT_LIBS = @XFT_LIBS@ +FFMPEG_CFLAGS = @FFMPEG_CFLAGS@ + # Note: see comment in ../driver/Makefile.in for explanation of X_LIBS, etc. # HACK_PRE = $(LIBS) $(X_LIBS) @@ -91,8 +93,8 @@ UTIL_OBJS = $(UTILS_BIN)/alpha.o $(UTILS_BIN)/colors.o \ $(UTILS_BIN)/colorbars.o \ $(UTILS_BIN)/textclient.o $(UTILS_BIN)/aligned_malloc.o \ $(UTILS_BIN)/thread_util.o $(UTILS_BIN)/pow2.o \ - $(UTILS_BIN)/xft.o $(UTILS_BIN)/utf8wc.o \ - $(UTILS_BIN)/font-retry.o + $(UTILS_BIN)/xft.o $(UTILS_BIN)/xftwrap.o \ + $(UTILS_BIN)/utf8wc.o $(UTILS_BIN)/font-retry.o SRCS = xscreensaver-getimage.c \ attraction.c blitspin.c bouboule.c braid.c bubbles.c \ @@ -127,7 +129,7 @@ SRCS = xscreensaver-getimage.c \ tessellimage.c delaunay.c recanim.c binaryring.c \ glitchpeg.c vfeedback.c scooter.c webcollage-cocoa.m \ webcollage-helper-cocoa.m testx11.c marbling.c \ - binaryhorizon.c droste.c ffmpeg-out.c + binaryhorizon.c droste.c ffmpeg-out.c ansi-tty.c SCRIPTS = xscreensaver-getimage-file xscreensaver-getimage-video \ xscreensaver-text vidwhacker webcollage @@ -166,7 +168,7 @@ OBJS = attraction.o blitspin.o bouboule.o braid.o bubbles.o \ asm6502.o abstractile.o lcdscrub.o hexadrop.o \ tessellimage.o delaunay.o recanim.o binaryring.o \ glitchpeg.o vfeedback.o scooter.o testx11.o marbling.o \ - binaryhorizon.o droste.o + binaryhorizon.o droste.o ansi-tty.o EXES = attraction blitspin bouboule braid decayscreen deco \ drift flame galaxy grav greynetic halo \ @@ -213,7 +215,7 @@ ANIM_OBJS = recanim.o ffmpeg-out.o HDRS = screenhack.h screenhackI.h fps.h fpsI.h xlockmore.h \ xlockmoreI.h automata.h bubbles.h ximage-loader.h \ apple2.h analogtv.h pacman.h pacman_ai.h pacman_level.h \ - asm6502.h delaunay.h recanim.h ffmpeg-out.h + asm6502.h delaunay.h recanim.h ffmpeg-out.h ansi-tty.h MEN = anemone.man apollonian.man attraction.man \ blaster.man blitspin.man bouboule.man braid.man bsod.man \ bumps.man ccurve.man compass.man coral.man \ @@ -400,9 +402,9 @@ distclean: clean # Adds all current dependencies to Makefile depend: - $(DEPEND) -s '# DO NOT DELETE: updated by make depend' \ - $(DEPEND_FLAGS) -- \ - $(INCLUDES) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \ + $(DEPEND) -s '# DO NOT DELETE: updated by make depend' \ + $(DEPEND_FLAGS) -- \ + $(INCLUDES) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) $(FFMPEG_CFLAGS) -- \ $(SRCS) # Adds some dependencies to Makefile.in -- not totally accurate, but pretty @@ -410,24 +412,24 @@ depend: # to include only dependencies on files which are themselves a part of this # package. distdepend:: m6502.h - @echo updating dependencies in `pwd`/Makefile.in... ; \ - $(DEPEND) -w 0 -f - \ - -s '# DO NOT DELETE: updated by make distdepend' $(DEPEND_FLAGS) -- \ - $(INCLUDES_1) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \ - $(SRCS) 2>/dev/null | \ - sort -d | \ - ( \ - awk '/^# .*Makefile.in ---/,/^# DO .*distdepend/' < Makefile.in ; \ - sed -e '/^#.*/d' \ - -e 's@ \./@ @g;s@ /[^ ]*@@g;/^.*:$$/d' \ - -e 's@\.\./utils@$$(UTILS_SRC)@g' \ - -e 's@ \([^$$]\)@ $$(srcdir)/\1@g' \ - -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' \ - -e 's@ $$(srcdir)/\(m6502.h\)@ \1@g' \ - -e 's@ $$(srcdir)/\(images/gen/\)@ \1@g' \ - -e 's@ $$(HACK_SRC)/\(images/gen/\)@ \1@g' ; \ - echo '' \ - ) > /tmp/distdepend.$$$$ && \ + @echo updating dependencies in `pwd`/Makefile.in... ; \ + $(DEPEND) -w 0 -f - \ + -s '# DO NOT DELETE: updated by make distdepend' $(DEPEND_FLAGS) -- \ + $(INCLUDES_1) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) $(FFMPEG_CFLAGS) -- \ + $(SRCS) 2>/dev/null | \ + sort -d | \ + ( \ + awk '/^# .*Makefile.in ---/,/^# DO .*distdepend/' < Makefile.in ; \ + sed -e '/^#.*/d' \ + -e 's@ \./@ @g;s@ /[^ ]*@@g;/^.*:$$/d' \ + -e 's@\.\./utils@$$(UTILS_SRC)@g' \ + -e 's@ \([^$$]\)@ $$(srcdir)/\1@g' \ + -e 's@ $$(srcdir)/\(.*config.h\)@ \1@g' \ + -e 's@ $$(srcdir)/\(m6502.h\)@ \1@g' \ + -e 's@ $$(srcdir)/\(images/gen/\)@ \1@g' \ + -e 's@ $$(HACK_SRC)/\(images/gen/\)@ \1@g' ; \ + echo '' \ + ) > /tmp/distdepend.$$$$ && \ mv /tmp/distdepend.$$$$ Makefile.in TAGS: tags @@ -456,7 +458,7 @@ check_men: fi validate_xml: - @cd $(srcdir) && ./check-configs.pl $(EXES) + @cd $(srcdir) && ./check-configs.pl --force $(EXES) munge_ad_file: @echo "Updating hack list in XScreenSaver.ad.in..." ; \ @@ -503,7 +505,7 @@ $(DRIVER_BIN)/prefs.o: # How we build object files in this directory. -HACK_CFLAGS_BASE=$(INCLUDES) $(DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) +HACK_CFLAGS_BASE=$(INCLUDES) $(DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) $(FFMPEG_CFLAGS) .c.o: $(CC) -c $(HACK_CFLAGS_BASE) $< @@ -527,6 +529,7 @@ THRL = $(THREAD_CFLAGS) $(THREAD_LIBS) ATV = analogtv.o $(SHM) $(THRO) APPLE2 = apple2.o $(ATV) TEXT = $(UTILS_BIN)/textclient.o +TTY = ansi-tty.o CC_HACK = $(CC) $(LDFLAGS) @@ -669,11 +672,12 @@ interference: interference.o $(HACK_OBJS) $(COL) $(SHM) $(THRO) $(DBE) truchet: truchet.o $(HACK_OBJS) $(COL) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(HACK_LIBS) -bsod: bsod.o $(HACK_OBJS) $(GRAB) $(APPLE2) $(PNG) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(GRAB) $(APPLE2) $(PNG) $(PNG_LIBS) $(THRL) +BSOD=$(HACK_OBJS) $(GRAB) $(APPLE2) $(PNG) $(UTILS_BIN)/xftwrap.o +bsod: bsod.o $(BSOD) + $(CC_HACK) -o $@ $@.o $(BSOD) $(PNG_LIBS) $(THRL) -apple2: apple2.o apple2-main.o $(HACK_OBJS) $(ATV) $(GRAB) $(TEXT) $(PNG) - $(CC_HACK) -o $@ $@.o apple2-main.o $(HACK_OBJS) $(ATV) $(GRAB) $(TEXT) $(PNG) $(PNG_LIBS) $(TEXT_LIBS) $(THRL) +apple2: apple2.o apple2-main.o $(HACK_OBJS) $(ATV) $(GRAB) $(TEXT) $(PNG) $(TTY) + $(CC_HACK) -o $@ $@.o apple2-main.o $(HACK_OBJS) $(ATV) $(GRAB) $(TEXT) $(PNG) $(PNG_LIBS) $(TEXT_LIBS) $(THRL) $(TTY) xanalogtv: xanalogtv.o $(HACK_OBJS) $(ATV) $(GRAB) $(PNG) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(ATV) $(GRAB) $(PNG) $(PNG_LIBS) $(HACK_LIBS) $(THRL) @@ -728,8 +732,8 @@ spotlight: spotlight.o $(HACK_OBJS) $(GRAB) critical: critical.o $(HACK_OBJS) $(COL) $(ERASE) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS) -phosphor: phosphor.o $(HACK_OBJS) $(TEXT) $(COL) $(PNG) - $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(TEXT) $(COL) $(PNG) $(PNG_LIBS) $(TEXT_LIBS) +phosphor: phosphor.o $(HACK_OBJS) $(TEXT) $(COL) $(PNG) $(TTY) + $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(TEXT) $(COL) $(PNG) $(TTY) $(PNG_LIBS) $(TEXT_LIBS) xmatrix: xmatrix.o $(HACK_OBJS) $(TEXT) $(PNG) $(CC_HACK) -o $@ $@.o $(HACK_OBJS) $(TEXT) $(PNG) $(PNG_LIBS) $(TEXT_LIBS) @@ -1116,6 +1120,22 @@ anemotaxis.o: $(UTILS_SRC)/visual.h anemotaxis.o: $(UTILS_SRC)/xdbe.h anemotaxis.o: $(UTILS_SRC)/xft.h anemotaxis.o: $(UTILS_SRC)/yarandom.h +ansi-tty.o: $(srcdir)/ansi-tty.h +ansi-tty.o: ../config.h +ansi-tty.o: $(srcdir)/fps.h +ansi-tty.o: $(srcdir)/recanim.h +ansi-tty.o: $(srcdir)/screenhackI.h +ansi-tty.o: $(srcdir)/screenhack.h +ansi-tty.o: $(UTILS_SRC)/colors.h +ansi-tty.o: $(UTILS_SRC)/font-retry.h +ansi-tty.o: $(UTILS_SRC)/grabclient.h +ansi-tty.o: $(UTILS_SRC)/hsv.h +ansi-tty.o: $(UTILS_SRC)/resources.h +ansi-tty.o: $(UTILS_SRC)/usleep.h +ansi-tty.o: $(UTILS_SRC)/utf8wc.h +ansi-tty.o: $(UTILS_SRC)/visual.h +ansi-tty.o: $(UTILS_SRC)/xft.h +ansi-tty.o: $(UTILS_SRC)/yarandom.h ant.o: $(srcdir)/automata.h ant.o: ../config.h ant.o: $(srcdir)/fps.h @@ -1150,6 +1170,7 @@ apollonian.o: $(UTILS_SRC)/yarandom.h apollonian.o: $(srcdir)/xlockmoreI.h apollonian.o: $(srcdir)/xlockmore.h apple2-main.o: $(srcdir)/analogtv.h +apple2-main.o: $(srcdir)/ansi-tty.h apple2-main.o: $(srcdir)/apple2.h apple2-main.o: ../config.h apple2-main.o: $(srcdir)/fps.h @@ -1360,6 +1381,7 @@ bsod.o: $(UTILS_SRC)/thread_util.h bsod.o: $(UTILS_SRC)/usleep.h bsod.o: $(UTILS_SRC)/visual.h bsod.o: $(UTILS_SRC)/xft.h +bsod.o: $(UTILS_SRC)/xftwrap.h bsod.o: $(UTILS_SRC)/xshm.h bsod.o: $(UTILS_SRC)/yarandom.h bsod.o: $(srcdir)/ximage-loader.h @@ -2672,6 +2694,7 @@ petri.o: $(UTILS_SRC)/usleep.h petri.o: $(UTILS_SRC)/visual.h petri.o: $(UTILS_SRC)/xft.h petri.o: $(UTILS_SRC)/yarandom.h +phosphor.o: $(srcdir)/ansi-tty.h phosphor.o: ../config.h phosphor.o: $(srcdir)/fps.h phosphor.o: images/gen/6x10font_png.h diff --git a/hacks/analogtv-cli.c b/hacks/analogtv-cli.c index 74da5d0a..5caec0fb 100644 --- a/hacks/analogtv-cli.c +++ b/hacks/analogtv-cli.c @@ -1,4 +1,4 @@ -/* xanalogtv-cli, Copyright © 2018-2023 Jamie Zawinski +/* xanalogtv-cli, Copyright © 2018-2025 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -996,10 +996,11 @@ analogtv_convert (const char **infiles, const char *outfile, static void usage(const char *err) { - if (err) fprintf (stderr, "%s: %s unknown\n", progname, err); - fprintf (stderr, "usage: %s [--verbose] [--duration secs] [--slideshow secs]" - " [--audio mp3-file] [--powerup] [--size WxH]" - " infile.png ... outfile.mp4\n", + if (err && *err) fprintf (stderr, "%s: %s unknown\n", progname, err); + fprintf (stderr, + "usage: %s [--verbose] [--duration secs] [--slideshow secs]\n" + "\t\t [--audio mp3-file] [--powerup] [--size WxH]\n" + "\t\t infile.png infile2.png ... outfile.mp4\n", progname); exit (1); } @@ -1035,6 +1036,11 @@ main (int argc, char **argv) else if (!strcmp(argv[i], "-vvv")) verbose_p += 3; else if (!strcmp(argv[i], "-vvvv")) verbose_p += 4; else if (!strcmp(argv[i], "-vvvvv")) verbose_p += 5; + else if (!strcmp(argv[i], "-vvvvvv")) verbose_p += 6; + else if (!strcmp(argv[i], "-vvvvvvv")) verbose_p += 7; + else if (!strcmp(argv[i], "-vvvvvvvv")) verbose_p += 8; + else if (!strcmp(argv[i], "-vvvvvvvvv")) verbose_p += 9; + else if (!strcmp(argv[i], "-vvvvvvvvvv")) verbose_p += 10; else if (!strcmp(argv[i], "-duration") && argv[i+1]) { char dummy; @@ -1080,6 +1086,17 @@ main (int argc, char **argv) outfile = infiles[nfiles-1]; infiles[--nfiles] = 0; + for (i = 0; i < nfiles; i++) + { + const char *f = infiles[i]; + struct stat st; + if (stat (f, &st)) + { + fprintf (stderr, "%s: %s does not exist\n", progname, f); + usage(""); + } + } + if (nfiles == 1) slideshow = duration; diff --git a/hacks/ansi-tty.c b/hacks/ansi-tty.c new file mode 100644 index 00000000..a91f364c --- /dev/null +++ b/hacks/ansi-tty.c @@ -0,0 +1,1930 @@ +/* xscreensaver, Copyright © 2025 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * An ANSI (VT100) terminal emulator. Reads control codes and renders the + * screen into a character grid. Other programs (apple2 and phosphor) then + * copy that layout to the screen while applying their own text styling. + * + * https://en.wikipedia.org/wiki/ANSI_escape_code + * https://vt100.net/docs/vt100-ug/chapter3.html + * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * https://en.wikipedia.org/wiki/ISO/IEC_2022 + * https://invisible-island.net/vttest/ + * https://github.com/mattiase/wraptest + */ + +#include "screenhack.h" +#include "ansi-tty.h" +#include "utf8wc.h" + +#define ESC 0x1B +#define CSI "\x1B[" + +# undef UNDEF +# define UNDEF -0xFFFF + +struct tty_state { + char buf[255], buf2[255]; + int idx, idx2; + int awaiting_st; + int unicrud; + int auto_wrap_p; + int origin_relative_p; + int linefeed_p; + + /* A fun quirk about ANSI / VT100 cursor addressing: When a character is + printed in column 80, the insertion point does not wrap to the next line + until the 81st character is printed, which will then appear in the + leftmost column of the following line. In this case, the cursor blinks + atop the 80th character instead of after it. This means that a cursor at + position 80 is visually ambiguous with one at position 79. + + Likewise, a character printed in the bottom right cell does not cause the + screen to scroll up by one line until the *next* character is printed. + + However, this only applies to cursor coordinates caused by text insertion. + Inserting "X" at column 80 lets cursor.x go to 81; but if at column 70 + and you do "move right by 20", the cursot ends up at 80, not 81. Fun! + + Details: https://github.com/mattiase/wraptest + */ + int lcf; /* Last Column Flag */ + + struct { int y1, y2; } scroll; + struct { int x, y, lcf; + tty_flag flags; } saved; + tty_flag flags; + tty_flag g0, g1; + tty_color fg, bg; + + char *tabs; /* 1 in each column that has a tab stop set. */ + + FILE *log_file; +}; + + +/* The DEC Special Graphics 8-bit character set used by vt100. + It is unclear to me if this was incorporated into ANSI. + */ +const unsigned long ansi_graphics_unicode[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00-0F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10-1F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20-2F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30-3F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-4F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' ', /* 50-5F */ + 0x25C6, /* 0x60 ` ◆ BLACK DIAMOND */ + 0x2592, /* 0x61 a ▒ MEDIUM SHADE */ + 0x2409, /* 0x62 b ␉ SYMBOL FOR HORIZONTAL TABULATION */ + 0x240C, /* 0x63 c ␌ SYMBOL FOR FORM FEED */ + 0x240D, /* 0x64 d ␍ SYMBOL FOR CARRIAGE RETURN */ + 0x240A, /* 0x65 e ␊ SYMBOL FOR LINE FEED */ + 0x00B0, /* 0x66 f ° DEGREE SIGN */ + 0x00B1, /* 0x67 g ± PLUS-MINUS SIGN */ + 0x2424, /* 0x68 h ␤ SYMBOL FOR NEWLINE */ + 0x240B, /* 0x69 i ␋ SYMBOL FOR VERTICAL TABULATION */ + 0x2518, /* 0x6A j ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + 0x2510, /* 0x6B k ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ + 0x250C, /* 0x6C l ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + 0x2514, /* 0x6D m └ BOX DRAWINGS LIGHT UP AND RIGHT */ + 0x253C, /* 0x6E n ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + 0x23BA, /* 0x6F o ⎺ HORIZONTAL SCAN LINE-1 */ + 0x23BB, /* 0x70 p ⎻ HORIZONTAL SCAN LINE-3 */ + 0x2500, /* 0x71 q ─ BOX DRAWINGS LIGHT HORIZONTAL */ + 0x23BC, /* 0x72 r ⎼ HORIZONTAL SCAN LINE-7 */ + 0x23BD, /* 0x73 s ⎽ HORIZONTAL SCAN LINE-9 */ + 0x251C, /* 0x74 t ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + 0x2524, /* 0x75 u ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + 0x2534, /* 0x76 v ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + 0x252C, /* 0x77 w ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + 0x2502, /* 0x78 x │ BOX DRAWINGS LIGHT VERTICAL */ + 0x2264, /* 0x79 y ≤ LESS-THAN OR EQUAL TO */ + 0x2265, /* 0x7A z ≥ GREATER-THAN OR EQUAL TO */ + 0x03C0, /* 0x7B { π GREEK SMALL LETTER PI */ + 0x2260, /* 0x7C | ≠ NOT EQUAL TO */ + 0x00A3, /* 0x7D } £ POUND SIGN */ + 0x00B7, /* 0x7E ~ · MIDDLE DOT */ + 0, /* 0x7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-9F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0-AF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0-BF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0-CF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0-DF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0-EF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0-FF */ +}; + + +static void +set_color (ansi_tty *tty, int fg_p, int color) +{ + tty_state *st = tty->state; + tty_color *c = (fg_p ? &st->fg : &st->bg); + if (color < countof(tty->cmap)) + { + *c = tty->cmap[color][fg_p ? 0 : 1]; + } + else + { + c->r = (color >> 16) & 0xFF; + c->g = (color >> 8) & 0xFF; + c->b = (color >> 0) & 0xFF; + } +} + + +static void +ansi_tty_default_tabs (ansi_tty *tty) +{ + int ts = 8; + int i; + char *tabs = tty->state->tabs; + for (i = 0; i < tty->width; i++) + tabs[i] = (i % ts) ? 0 : 1; +} + + +static void +ansi_tty_reset (ansi_tty *tty) +{ + int odebug = tty->debug_p; + FILE *olog = tty->state->log_file; + char *otabs = tty->state->tabs; + memset (tty->grid, 0, tty->width * tty->height * sizeof (*tty->grid)); + memset (tty->state, 0, sizeof(*tty->state)); + tty->state->scroll.y1 = 0; + tty->state->scroll.y2 = tty->height; + tty->state->auto_wrap_p = True; + tty->state->fg = tty->cmap[2][0]; /* Green */ + tty->state->bg = tty->cmap[0][1]; /* Black */ + tty->debug_p = odebug; + tty->state->log_file = olog; + tty->state->tabs = otabs; + ansi_tty_default_tabs (tty); +} + + +ansi_tty * +ansi_tty_init (int w, int h) +{ + ansi_tty *tty = (ansi_tty *) calloc (1, sizeof(*tty)); + if (!tty) abort(); + if (w <= 2 || h <= 2) abort(); + tty->width = w; + tty->height = h; + tty->grid = (tty_char *) calloc (w * h, sizeof (*tty->grid)); + tty->state = (tty_state *) calloc (1, sizeof(*tty->state)); + if (!tty->grid || !tty->state) abort(); + tty->state->tabs = (char *) calloc (w, 1); + ansi_tty_default_tabs (tty); + + tty->debug_p = 1; + +# if !defined(HAVE_MOBILE) && !defined(__OPTIMIZE__) + if (tty->debug_p >= 4) + { + const char *fn = "/tmp/ttylog.txt"; + tty->state->log_file = fopen (fn, "wb"); + if (!tty->state->log_file) + fprintf (stderr, "%s: unable to write %s\n", progname, fn); + else + fprintf (stderr, "%s: WARNING: logging to %s\n", progname, fn); + + /* Note: if you're trying to do playback using this log file, + be sure to do "stty -onlcr ; cat FILE" or the shell will + turn \r\n into \r\r\n. */ + } +# endif + + { + static const tty_color cmap[] = { /* VGA colors */ + { 0x00, 0x00, 0x00 }, /* 30 40 Black */ + { 0xAA, 0x00, 0x00 }, /* 31 41 Red */ + { 0x00, 0xAa, 0x00 }, /* 32 42 Green */ + { 0xAA, 0x55, 0x00 }, /* 33 43 Yellow */ + { 0x00, 0x00, 0xAA }, /* 34 44 Blue */ + { 0xAA, 0x00, 0xAA }, /* 35 45 Magenta */ + { 0x00, 0xAA, 0xAA }, /* 36 46 Cyan */ + { 0xAA, 0xAA, 0xAA }, /* 37 47 White */ + { 0x55, 0x55, 0x55 }, /* 90 100 Bright Black */ + { 0xFF, 0x55, 0x55 }, /* 91 101 Bright Red */ + { 0x55, 0xFF, 0x55 }, /* 92 102 Bright Green */ + { 0xFF, 0xFF, 0x55 }, /* 93 103 Bright Yellow */ + { 0x55, 0x55, 0xFF }, /* 94 104 Bright Blue */ + { 0xFF, 0x55, 0xFF }, /* 95 105 Bright Magenta */ + { 0x55, 0xFF, 0xFF }, /* 96 106 Bright Cyan */ + { 0xFF, 0xFF, 0xFF }, /* 97 107 Bright White */ + }; + int i; + for (i = 0; i < countof(cmap); i++) + { + tty->cmap[i][0] = cmap[i]; + tty->cmap[i][1] = cmap[i]; + } + } + + ansi_tty_reset (tty); + + if (tty->debug_p > 1) + fprintf (stderr, "%s: tty init %dx%d\n", progname, w, h); + + return tty; +} + +void +ansi_tty_free (ansi_tty *tty) +{ + if (tty->state->log_file) + fclose (tty->state->log_file); + free (tty->state->tabs); + free (tty->state); + free (tty); +} + +void ansi_tty_resize (ansi_tty *tty, int w, int h) +{ + tty_state *st = tty->state; + tty_char *grid2; + int x, y; + if (w <= 2 || h <= 2) abort(); + grid2 = (tty_char *) calloc (w * h, sizeof (*grid2)); + + for (y = 0; y < tty->height; y++) + for (x = 0; x < tty->width; x++) + if (x < w && y < h) + grid2[y * w + x] = tty->grid[y * tty->width + x]; + + free (tty->grid); + tty->grid = grid2; + tty->width = w; + tty->height = h; + + tty->state->tabs = (char *) realloc (tty->state->tabs, w); + + if (tty->x >= w) tty->x = w-1; + if (st->scroll.y1 > tty->height) st->scroll.y1 = tty->height; + if (st->scroll.y2 > tty->height) st->scroll.y2 = tty->height; + if (tty->y >= st->scroll.y2) tty->y = st->scroll.y2 - 1; + if (tty->y >= st->scroll.y2) tty->y = st->scroll.y2 - 1; + + if (tty->debug_p) + fprintf (stderr, "%s: tty resize %dx%d\n", progname, w, h); +} + + +/* Scroll lines up or down within the character grid. + */ +static void +tty_scroll (ansi_tty *tty, int lines) +{ + tty_state *st = tty->state; + unsigned char *top = (unsigned char *) + (tty->grid + tty->width * st->scroll.y1); + unsigned char *bot = (unsigned char *) + (tty->grid + (tty->width * st->scroll.y2)); + int total = bot - top; + int move = lines * tty->width * sizeof(*tty->grid); + + if ( lines >= st->scroll.y2 - st->scroll.y1 || + -lines >= st->scroll.y2 - st->scroll.y1) + { + /* Scrolling more lines than exist is clearing. */ + memset (top, 0, total); + } + else if (lines > 0) + { + memmove (top, top + move, total - move); + memset (top + total - move, 0, move); + } + else if (lines < 0) + { + move = -move; + memmove (top + move, top, total - move); + memset (top, 0, move); + } +} + + +/* Clear characters from the grid. + Start and end positions are inclusive. + */ +static void +tty_erase (ansi_tty *tty, int x1, int y1, int x2, int y2) +{ + int from, to; + tty_char *ch, *end; + + if (x1 < 0) x1 = 0; + if (x2 < 0) x2 = 0; + if (y1 < 0) y1 = 0; + if (y2 < 0) y2 = 0; + if (x1 > tty->width-1) x1 = tty->width-1; + if (x2 > tty->width-1) x2 = tty->width-1; + if (y1 > tty->height-1) y1 = tty->height-1; + if (y2 > tty->height-1) y2 = tty->height-1; + + from = y1 * tty->width + x1; + to = y2 * tty->width + x2; + if (from > to) abort(); + + ch = tty->grid + from; + end = tty->grid + to; + + while (ch <= end) + { +# if 1 + ch->c = 0; + ch->flags = 0; + ch->fg = tty->cmap[2][0]; /* Green */ + ch->bg = tty->cmap[0][1]; /* Black */ +# else + /* You might assume that turning on inverse and clearing to end of + line would give you an inverted line, but you would be wrong. */ + ch->c = tty->state->flags ? ' ' : 0; + ch->flags = tty->state->flags; + ch->fg = tty->state->fg; + ch->bg = tty->state->bg; +# endif + ch++; + } +} + + +/* Print a line describing the non-command text that was printed, + once enough of it has buffered up to be legible. NULL means flush. + */ +static void +tty_log_c (ansi_tty *tty, const char c) +{ + if (tty->debug_p > 2) + { + tty_state *st = tty->state; + char buf3[sizeof (st->buf2) * 4 + 100]; + char *in, *out; + + if (c) + { + st->buf2[st->idx2++] = c; + st->buf2[st->idx2] = 0; + } + + if (((c >= ' ' && c <= '~') || c == '\r' || c == 0x08) && + st->idx2 < sizeof(st->buf2) - 1) + return; + + in = st->buf2; + out = buf3; + *out = 0; + + while (*in) { + char c = *in++; + if (c >= ' ' && c <= '~') + { + *out++ = c; + *out = 0; + } + else + { + int pad = False; + if (c == 0x08) strcat (out, "\\b"); + else if (c == 0x09) strcat (out, "\\t"); + else if (c == 0x0A) strcat (out, "\\n"); + else if (c == 0x1B) strcat (out, "\\e"); + else if (c == 0x0D) strcat (out, "\\r"); + else + { + pad = True; + if (out > buf3 && out[-1] != ' ') + { + *out++ = ' '; + *out = 0; + } + sprintf (out, "\\x%02X", (unsigned char) c); + } + + out += strlen (out); + if (*in && pad) + { + *out++ = ' '; + *out = 0; + } + } + } + + if (out > buf3) + fprintf (stderr, "%s: txt: \"%s\"\n", progname, buf3); + + st->idx2 = 0; + st->buf2[0] = 0; + } +} + + +/* Print a line describing the terminal command being executed. + */ +static void +tty_log (ansi_tty *tty, const char *kind, int ok, const char *log, + int ac, const int *av, const char *cmd) +{ + if (tty->debug_p > (ok ? 1 : 0)) + { + char buf[1024], *s = buf; + int i; + + tty_log_c (tty, 0); /* Flush */ + + if (ac) *s++ = ':'; + *s = 0; + + for (i = 0; i < ac; i++) + { + if (av[i] == UNDEF) + sprintf (s, " -"); + else + sprintf (s, " %d", av[i]); + s += strlen(s); + } + if (!ok || tty->debug_p > 1) + { + int j = 0; + strcat (s, ": "); + s += strlen(s); + while (*cmd && j < 100) + { + if (*cmd == ESC) + strcat (s, "ESC "); + else if (*cmd < ' ' || *cmd > '~') + sprintf (s, "0x%02X", *cmd); + else + sprintf (s, "%c", *cmd); + + s += strlen(s); + cmd++; + j++; + } + } + + fprintf (stderr, "%s: %3s: %s%s%s\n", progname, kind, + (ok ? "" : "Unimplemented: "), log, buf); + } +} + + +/* Just gonna leave this here: + + % infocmp -x vt100 + Reconstructed via infocmp from file: /usr/share/terminfo/v/vt100 + vt100|vt100-am|DEC VT100 (w/advanced video), + OTbs, am, mc5i, msgr, xenl, xon, + cols#80, it#8, lines#24, vt#3, + acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, + bel=^G, blink=\E[5m$<2>, bold=\E[1m$<2>, + clear=\E[H\E[J$<50>, cr=\r, csr=\E[%i%p1%d;%p2%dr, + cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=\n, + cuf=\E[%p1%dC, cuf1=\E[C$<2>, + cup=\E[%i%p1%d;%p2%dH$<5>, cuu=\E[%p1%dA, + cuu1=\E[A$<2>, ed=\E[J$<50>, el=\E[K$<3>, el1=\E[1K$<3>, + enacs=\E(B\E)0, home=\E[H, ht=^I, hts=\EH, ind=\n, ka1=\EOq, + ka3=\EOs, kb2=\EOr, kbs=^H, kc1=\EOp, kc3=\EOn, kcub1=\EOD, + kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kent=\EOM, kf0=\EOy, + kf1=\EOP, kf10=\EOx, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kf5=\EOt, + kf6=\EOu, kf7=\EOv, kf8=\EOl, kf9=\EOw, lf1=pf1, lf2=pf2, + lf3=pf3, lf4=pf4, mc0=\E[0i, mc4=\E[4i, mc5=\E[5i, rc=\E8, + rev=\E[7m$<2>, ri=\EM$<5>, rmacs=^O, rmam=\E[?7l, + rmkx=\E[?1l\E>, rmso=\E[m$<2>, rmul=\E[m$<2>, + rs2=\E<\E>\E[?3;4;5l\E[?7;8h\E[r, sc=\E7, + sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;$<2>, + sgr0=\E[m\017$<2>, smacs=^N, smam=\E[?7h, smkx=\E[?1h\E=, + smso=\E[7m$<2>, smul=\E[4m$<2>, tbc=\E[3g, + u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?%[;0123456789]c, u9=\EZ, + + Reformatted for legibility: + + OTbs + auto_right_margin + prtr_silent + move_standout_mode + eat_newline_glitch + xon_xoff + cols#80 + init_tabs#8 + lines#24 + virtual_terminal#3 + + acs_chars = ``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~ + bell = ^G + enter_blink_mode = CSI 5 m + enter_bold_mode = CSI 1 m + clear_screen = CSI H + CSI J + carriage_return = \r + change_scroll_region = CSI ; r + parm_left_cursor = CSI D + cursor_left = ^H + parm_down_cursor = CSI B + cursor_down = \n + parm_right_cursor = CSI C + cursor_right = CSI C + cursor_address = CSI ; H + parm_up_cursor = CSI A + cursor_up = CSI A + clr_eos = CSI J + clr_eol = CSI K + clr_bol = CSI 1 K + ena_acs = ESC ( B ESC ) 0 + cursor_home = CSI H + tab = ^I + set_tab = ESC H + scroll_forward = \n + key_a1 = ESC O q + key_a3 = ESC O s + key_b2 = ESC O r + key_backspace = ^H + key_c1 = ESC O p + key_c3 = ESC O n + key_left = ESC O D + key_down = ESC O B + key_right = ESC O C + key_up = ESC O A + key_enter = ESC O M + key_f0 = ESC O y + key_f1 = ESC O P + key_f10 = ESC O x + key_f2 = ESC O Q + key_f3 = ESC O R + key_f4 = ESC O S + key_f5 = ESC O t + key_f6 = ESC O u + key_f7 = ESC O v + key_f8 = ESC O l + key_f9 = ESC O w + lab_f1 = pf1 + lab_f2 = pf2 + lab_f3 = pf3 + lab_f4 = pf4 + print_screen = CSI 0 i + prtr_off = CSI 4 i + prtr_on = CSI 5 i + restore_cursor = ESC 8 + enter_reverse_mode = CSI 7 m + scroll_reverse = ESC M + exit_alt_charset_mode = ^O + exit_am_mode = CSI ? 7 l + keypad_local = CSI ? 1 l ESC > + exit_standout_mode = CSI m + exit_underline_mode = CSI m + reset_2string = ESC < ESC > + CSI ? 3 ; 4 ; 5 l + CSI ? 7 ; 8 h + CSI r + save_cursor = ESC 7 + + set_attributes = CSI 0 + IF %p1 | %p6 THEN ; 1 ENDIF + IF %p2 THEN ; 4 ENDIF + IF %p1 | %p3 THEN ; 7 ENDIF + IF %p4 THEN ; 5 ENDIF + m + IF %p9 THEN \016 + ELSE \017 ENDIF + + exit_attribute_mode = CSI m \017 + enter_alt_charset_mode = ^N + enter_am_mode = CSI ? 7 h + keypad_xmit = CSI ? 1 h ESC = + enter_standout_mode = CSI 7 m + enter_underline_mode = CSI 4 m + clear_all_tabs = CSI 3 g + user6 = CSI %i %d ; %d R + user7 = CSI 6 n + user8 = CSI ? %[;0123456789] c + user9 = ESC Z + */ + + +/* I find state machines soothing. If the thing you're writing is not + a state machine, it might be evil. + _______________________________________________________________ + / \ + | Tech enthusiasts: My entire house is smart. | + | | + | Tech workers: The only piece of technology in my house is a | + | printer and I keep a gun next to it so I can shoot it if it | + | makes a noise I don't recognize. -- PPathole, 2019 | + \ | + `---------------------------------------------------------------' + */ +void +ansi_tty_print (ansi_tty *tty, unsigned long c) +{ + tty_state *st = tty->state; + int done = False; + int scrolled_p = False; + + const char *kind = "?"; + int av[255]; + int ac = 0; + int i; + + if (st->log_file) + { + fputc ((char) c, st->log_file); /* Botches unicode */ + fflush (st->log_file); + } + +# define LOG(S) tty_log (tty, kind, True, (S), ac, av, st->buf) +# define UND(S) tty_log (tty, kind, False, (S), ac, av, st->buf) + + + /* Parse the command sequences. + + nF 20-2F SPC - / 2+ bytes, [20-2F]+ 30-7E + Fp 30-3F 0-9:;<=>? 2 bytes + Fe 40-5F @A-Zp\]^_ 2 bytes, or CSI: ESC [ ... C + Fs 60-7E `a-z{|}~ 2 bytes + */ + + /* WTF, BS and others are allowed within command sequences! */ + if (st->idx > 0 && c < ' ') + goto SELF_INSERT_INTERLUDE; + + st->buf[st->idx++] = c; + st->buf[st->idx] = 0; + + + /******************************************************************** ESC */ + + + if (st->idx >= sizeof(st->buf) - 2) /* Buffer overflow */ + { + kind = "?"; + done = True; + UND ("OVERFLOW"); + } + else if (st->awaiting_st) + { + kind = "ST0"; + /* Some "Fe" commands swallow all bytes until an "ST" string terminator + command is received, so just keep going, filling the buffer. */ + } + else if (c == ESC) /* Starting any command */ + { + kind = "ESC"; + if (st->idx > 1) + LOG ("Aborted by ESC"); + st->idx = 1; + } + + + /********************************************************************* nF */ + + + else if (st->idx == 2 && /* nF escape sequence start */ + st->buf[0] == ESC && + c >= 0x20 && /* !"#$%&'()*+,-./ */ + c <= 0x2F) + { + kind = "nFa"; + } + else if (st->idx > 2 && /* nF escape sequence cont. */ + st->buf[0] == ESC && + st->buf[1] >= 0x20 && /* !"#$%&'()*+,-./ */ + st->buf[1] <= 0x2F && + c >= 0x20 && /* !"#$%&'()*+,-./ */ + c <= 0x2F) + { + kind = "nFb"; + } + else if (st->idx > 2 && /* nF escape sequence end */ + st->buf[0] == ESC && + st->buf[1] >= 0x20 && /* !"#$%&'()*+,-./ */ + st->buf[1] <= 0x2F && + c >= 0x30 && /* 0 - ~ */ + c <= 0x7E) + { + kind = "nF"; + done = True; + + switch (st->idx) { + case 2: /* ESC ? */ + kind = "nF2"; + switch (st->buf[1]) { + case '`': UND ("Disable manual input"); break; + case 'a': UND ("Interrupt"); break; + case 'b': UND ("Enable manual input"); break; + case 'c': LOG ("Reset"); + ansi_tty_reset (tty); + break; + case 'd': UND ("Coding method delimiter"); break; + case 'n': UND ("Locking shift 1"); break; + case 'o': UND ("Locking shift 3"); break; + case '|': UND ("Locking shift 3R"); break; + case '}': UND ("Locking shift 2R"); break; + case '~': UND ("Locking shift 1R"); break; + default: UND ("Unknown"); break; + } + break; + + case 3: /* ESC ? ? */ + kind = "nF3"; + switch (st->buf[1]) { + case '!': UND ("C0-designate"); break; + case '"': UND ("C1-designate"); break; + + case '#': /* ESC # ? */ + st->lcf = False; + switch (st->buf[2]) { + case '3': UND ("Double Height Top"); break; + case '4': UND ("Double Height Bottom"); break; + case '5': UND ("Single Width"); break; + case '6': UND ("Double Width"); break; + case '8': LOG ("Screen Alignment"); + { + tty_char *ch = tty->grid; + tty_char *end = tty->grid + (tty->width * tty->height); + while (ch < end) + { + ch->c = 'E'; + ch++; + } + } + break; + default: UND ("Unknown #"); break; + } + break; + + case '$': UND ("G0 designate"); break; + + case '%': /* ESC % ? */ + switch (st->buf[2]) { + case '@': UND ("Designate coding"); break; + case 'B': UND ("UTF-1"); break; + case 'G': UND ("UTF-8"); break; + case '/': UND ("UTF-32"); break; + default: UND ("Unknown %"); break; + } + break; + case '&': UND ("Identify revised registration"); break; + case '\'': UND ("Not used"); break; + + case '(': /* ESC ( ? */ + case ')': /* ESC ( ? */ + { + int g0_p = (st->buf[1] == '('); + tty_flag *gg = (g0_p ? &st->g0 : &st->g1); + + /* This says which character set g0 and g1 indicate. */ + *gg = 0; + switch (st->buf[2]) { + case '0': LOG ("G0-designate 94-set: Line Drawing"); + *gg = TTY_SYMBOLS; + break; + + /* We could map these various fonts, particularly the + line- and box-drawing font, to their corresponding + Unicode code points. But since neither Phosphor and + Apple2 can display non-Latin1 characters, that + wouldn't do us any good right now. */ + + case '1': UND ("Gx-designate 94: Alt Char"); break; + case '2': UND ("Gx-designate 94: Alt Special"); break; + case '5': UND ("Gx-designate 94: Finnish"); break; + case '7': UND ("Gx-designate 94: Swedish"); break; + case '9': UND ("Gx-designate 94: French Canadian"); break; + case '<': UND ("Gx-designate 94: DEC Supplemental"); break; + case '>': UND ("Gx-designate 94: DEC Technical"); break; + case 'A': UND ("Gx-designate 94: UK"); break; + case 'B': LOG ("Gx-designate 94: ASCII"); break; + case 'C': UND ("Gx-designate 94: Finnish"); break; + case 'H': UND ("Gx-designate 94: Swedish"); break; + case 'I': UND ("Gx-designate 94: JIS Katakana"); break; + case 'J': UND ("Gx-designate 94: JIS Roman"); break; + case 'K': UND ("Gx-designate 94: German"); break; + case 'Q': UND ("Gx-designate 94: French Canadian"); break; + case 'R': UND ("Gx-designate 94: French"); break; + case 'Y': UND ("Gx-designate 94: Italian"); break; + case 'Z': UND ("Gx-designate 94: Spanish"); break; + case 'f': UND ("Gx-designate 94: French"); break; + default: UND ("Unknown Gx"); break; + } + } + break; + /* ESC # # */ + + case '*': UND ("G2-designate 94"); break; + case '+': UND ("G3-designate 94"); break; + case ',': UND ("Not used"); break; + case '-': UND ("G1-designate 96"); break; + case '.': UND ("G2-designate 96"); break; + case '/': UND ("G3-designate 96"); break; + + case ' ': /* ESC SP # */ + switch (st->buf[2]) { + case 'A': UND ("G0 in GL, GR unused"); break; + case 'B': UND ("G0 and G1 to GL"); break; + case 'C': UND ("G0 in GL, G1 in GR, no lock"); break; + case 'D': UND ("G0 in GL, G1 in GR 8-bit"); break; + case 'E': UND ("Shift preserved"); break; + case '"': UND ("C1 controls esc"); break; + case 'G': UND ("C1 controls CR"); break; + case 'H': UND ("94-char graphical"); break; + case 'I': UND ("94-char and/or 96-char"); break; + case 'J': UND ("7-bit"); break; + case 'K': UND ("8-bit"); break; + case 'L': UND ("ISO/IEC 4873 1"); break; + case 'M': UND ("ISO/IEC 4873 2"); break; + case 'N': UND ("ISO/IEC 4873 3"); break; + case 'P': UND ("SI / LS0"); break; + case 'R': UND ("SO / LS1"); break; + case 'S': UND ("LS1R 8-bit"); break; + case 'T': UND ("LS2"); break; + case 'U': UND ("LS2R 8-bit"); break; + case 'V': UND ("LS3"); break; + case 'W': UND ("LS3R 8-bit"); break; + case 'Z': UND ("SS2"); break; + case '%': UND ("Designate other"); break; + case '[': UND ("SS2"); break; + case '\\': UND ("Single-shift GR"); break; + default: UND ("Unknown SP"); break; + } + break; + default: UND ("Unknown"); break; + } + break; + + case 4: /* ESC # # # */ + kind = "nF4"; + switch (st->buf[1]) { + case '$': /* ESC $ # # */ + switch (st->buf[2]) { + case '(': UND ("G0 designate"); break; + case ')': UND ("G1-designate"); break; + case '*': UND ("G2-designate"); break; + case '+': UND ("G3-designate multi 94"); break; + case ',': UND ("Not used"); break; + case '-': UND ("G1-designate multi 96"); break; + case '.': UND ("G2-designate multi 96"); break; + case '/': UND ("G3-designate multi 96"); break; + default: UND ("Unknown $"); break; + } + case '%': /* ESC % # # */ + switch (st->buf[2]) { + case '/': + switch (st->buf[3]) { + case 'I': UND ("UTF-8"); break; + case 'L': UND ("UTF-16"); break; + default: UND ("Unknown %"); break; + } + break; + default: UND ("Unknown"); break; + } + break; + default: UND ("Unknown"); break; + } + break; + default: UND ("Unknown"); break; + } + } + + + /********************************************************************* Fp */ + + + else if (st->idx == 2 && /* Fp escape sequence */ + st->buf[0] == ESC && + c >= 0x30 && /* 0-9:;<=>? */ + c <= 0x3F) + { + kind = "Fp"; + done = True; + + switch (c) { + case '7': LOG ("Save Cursor"); + st->saved.flags = st->flags; + st->saved.lcf = st->lcf; + st->saved.x = tty->x; + st->saved.y = tty->y; + break; + case '8': LOG ("Restore Cursor"); + st->flags = st->saved.flags; + st->lcf = st->saved.lcf; + tty->x = st->saved.x; + tty->y = st->saved.y; + break; + case '9': UND ("Forward Index"); break; + case '=': /* UND ("App Keypad");*/ break; + case '<': UND ("ANSI mode"); break; + case '>': /* UND ("Normal Keypad");*/ break; + default: UND ("Unknown"); break; + } + } + else if (st->idx >= 3 && /* CSI: Sequence Introducer */ + st->buf[0] == ESC && /* intermediate bytes */ + st->buf[1] == '[' && /* ESC [ ... C */ + ((c >= 0x30 && c <= 0x3F) || /* parameters 0–9:;<=>? */ + (c >= 0x20 && c <= 0x2F))) /* others !"#$%&'()*+,-./ */ + { + kind = "CSIa"; + } + + + /******************************************************************** CSI */ + + + else if (st->idx >= 3 && /* CSI: Sequence Introducer */ + st->buf[0] == ESC && /* final byte */ + st->buf[1] == '[' && /* ESC [ ... C */ + c >= 0x40 && /* cmd @A–Z[\]^_`a–z{|}~ */ + c <= 0x7E) + { + kind = "CSI"; + done = True; + + /* Parse the "80;24;365" args into 'av'. */ + { + int any = False; + for (i = 0; i < countof(av); i++) + av[i] = UNDEF; + for (i = 2; i < st->idx - 1; i++) + { + if (st->buf[i] == ';' && ac < countof(av)-1) + { + if (ac >= countof(av) - 2) + break; + ac++; + av[ac] = 0; + any = True; + } + else if (st->buf[i] >= '0' && st->buf[i] <= '9') + { + if (av[ac] == UNDEF) + av[ac] = 0; + av[ac] = (av[ac] * 10) + (st->buf[i] - '0'); + any = True; + } + else if (st->buf[i] >= 0x3C && st->buf[i] <= 0x3F) + ; /* Characters "<=>?" indicate private commands. */ + else if (st->buf[i] == '!') + ; /* What's this? */ + else + UND ("Weird parameters"); + } + if (any) ac++; + } + + switch (c) { + case '@': st->lcf = False; UND ("Shift left"); break; + case 'A': LOG ("Cursor Up"); + /* "CSI n SP A" means shift right n cols */ + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + tty->y -= av[0]; + st->lcf = False; + scrolled_p = True; + break; + case 'B': LOG ("Cursor Down"); + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + tty->y += av[0]; + st->lcf = False; + scrolled_p = True; + break; + case 'C': LOG ("Cursor Forward"); + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + tty->x += av[0]; + st->lcf = False; + scrolled_p = True; + break; + case 'D': LOG ("Cursor Back"); + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + tty->x -= av[0]; + st->lcf = False; + scrolled_p = True; + break; + case 'E': LOG ("Cursor Next Line"); + if (av[0] == UNDEF) av[0] = 1; + tty->x = 0; + tty->y += av[0]; + scrolled_p = True; + /* Set lcf to False here? */ + break; + case 'F': LOG ("Cursor Previous Line"); + if (av[0] == UNDEF) av[0] = 1; + tty->x = 0; + tty->y -= av[0]; + scrolled_p = True; + /* Set lcf to False here? */ + break; + case 'G': LOG ("Cursor Horizontal Abs"); + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + tty->x = av[0]-1; + /* Set lcf to False here? */ + break; + case 'H': LOG ("Cursor Position"); + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + if (av[1] == UNDEF || av[1] == 0) av[1] = 1; + tty->y = av[0]-1; + tty->x = av[1]-1; + if (st->origin_relative_p) tty->y += st->scroll.y1; + st->lcf = False; + break; + + case 'I': LOG ("Fwd Tab Stop"); + { + int i; + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + /* Move forward N tab stops. */ + /* Set lcf to False here? */ + for (i = 0; i < av[0]; i++) + { + tty->x++; + while (tty->x < tty->width && + !st->tabs[tty->x]) + tty->x++; + } + } + break; + + case 'J': /* Erase in Display */ + st->lcf = False; + if (av[0] == UNDEF || av[0] == 0) + { LOG ("Erase to end of screen"); + tty_erase (tty, + tty->x, tty->y, + tty->width-1, tty->height-1); + } + else if (av[0] == 1) + { LOG ("Erase to start of screen"); + tty_erase (tty, + 0, 0, + tty->x-1, tty->y); + } + else if (av[0] == 2 || av[0] == 3) + { LOG ("Erase screen"); + tty_erase (tty, + 0, 0, + tty->width-1, tty->height-1); + } + /* CSI ? n J" are vt220 */ + break; + + case 'K': /* Erase in Line */ + st->lcf = False; + if (av[0] == UNDEF || av[0] == 0) + { LOG ("Erase to end of line"); + tty_erase (tty, + tty->x, tty->y, + tty->width-1, tty->y); + } + else if (av[0] == 1) + { LOG ("Erase to start of line"); + tty_erase (tty, + 0, tty->y, + tty->x-1, tty->y); + } + else if (av[0] == 2 || av[0] == 3) + { LOG ("Erase line"); + tty_erase (tty, + 0, tty->y, + tty->width-1, tty->y); + } + break; + + case 'L': UND ("Insert lines"); break; + case 'M': UND ("Delete lines"); break; + case 'P': st->lcf = False; UND ("Delete chars"); break; + case 'Q': UND ("Palette stack"); break; + case 'R': UND ("Palette restore");break; + + case 'S': LOG ("Scroll Up"); + if (av[0] == UNDEF) av[0] = 1; + tty_scroll (tty, av[0]); + scrolled_p = True; + /* Set lcf to False here? */ + break; + case 'T': LOG ("Scroll Down"); + if (av[0] == UNDEF) av[0] = 1; + tty_scroll (tty, -av[0]); + scrolled_p = True; + /* Set lcf to False here? */ + break; + + case 'W': LOG ("Reset tabs"); + ansi_tty_default_tabs (tty); + break; + + case 'X': st->lcf = False; UND ("Erase chars"); break; + case 'Z': LOG ("Back tab stop"); + { + int i; + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + /* Move backward N tab stops. */ + for (i = 0; i < av[0]; i++) + { + tty->x--; + while (tty->x >= 0 && + !st->tabs[tty->x]) + tty->x--; + } + } + break; + + /* Unused: [\]_ */ + + case '^': UND ("Scroll down"); break; + case '`': UND ("Position abs"); break; + + case 'a': UND ("Position rel"); break; + case 'b': UND ("Repeat prev"); break; + + case 'c': /* Reports */ + switch (av[0]) { + case 0: LOG ("Report model"); + if (tty->tty_send) + { + char buf[40]; /* Base model */ + sprintf (buf, CSI "?%d;%dc", 1, 0); + (*tty->tty_send) (tty->closure, buf); + } + break; + default: UND ("Unknown report request"); break; + break; + } + break; + + case 'd': UND ("Pos abs"); break; + case 'e': UND ("Pos rel"); break; + + case 'f': LOG ("H/V Position"); + if (av[0] == UNDEF || av[0] == 0) av[0] = 1; + if (av[1] == UNDEF || av[1] == 0) av[1] = 1; + tty->y = av[0]-1; + tty->x = av[1]-1; + st->lcf = False; + break; + + case 'g': + if (av[0] == UNDEF) av[0] = 0; + switch (av[0]) { + case 0: LOG ("Clear tab"); + st->tabs[tty->x] = 0; + break; + case 1: LOG ("Set tab"); + st->tabs[tty->x] = 1; + break; + case 3: LOG ("Clear all tabs"); + memset (st->tabs, 0, tty->width); + break; + default: UND ("Unknown tab"); break; + } + break; + + case 'h': /* On */ + /* i,j,k are below */ + case 'l': /* Off */ + { + int on_p = (st->buf[st->idx-1] == 'h'); + switch (av[0]) { + case 1: + if (on_p) + /* LOG ("Application cursor keys") */; + else + /* LOG ("Normal cursor keys") */; + break; + case 2: UND ("USASCII sets G0-G3"); break; + /* Or ANSI/VT52 Mode? */ + case 3: + st->lcf = False; + if (on_p) UND ("132 Column Mode"); + else LOG ("80 Column Mode"); + break; + case 4: UND ("Smooth Scroll"); break; + case 5: + if (on_p) + LOG ("Reverse Video on"); + else + LOG ("Reverse Video off"); + tty->inverse_p = on_p; + break; + case 6: + st->lcf = False; + if (on_p) + LOG ("Origin Mode on"); + else + LOG ("Origin Mode off"); + st->origin_relative_p = on_p; + tty->x = 0; + tty->y = on_p ? st->scroll.y1 : 0; + break; + case 7: + tty->state->auto_wrap_p = on_p; + if (on_p) + LOG ("Auto-wrap on"); + else + LOG ("Auto-wrap off"); + if (!on_p) + st->lcf = False; + break; + case 8: UND ("Auto-Repeat Keys"); break; + case 9: UND ("Send Mouse"); break; + /* Or Interlace? */ + case 10: UND ("Show toolbar"); break; + case 12: UND ("Start blinking"); break; + case 13: UND ("Start blinking"); break; + case 14: UND ("Enable XOR"); break; + case 18: UND ("Print Form Feed"); break; + case 19: UND ("Print full screen"); break; + + case 20: + if (on_p) LOG ("Linefeed mode"); + else LOG ("Newline mode"); + st->linefeed_p = on_p; + break; + + case 25: UND ("Show cursor"); break; + case 30: UND ("Show scrollbar"); break; + case 35: UND ("Enable font-shifting"); break; + case 38: UND ("Enter Tektronix"); break; + case 40: UND ("Allow 80/132"); break; + case 41: UND ("more"); break; + case 42: UND ("National replacement"); break; + case 43: UND ("Graphic Expanded Print"); break; + case 44: UND ("Graphic Print Color"); break; + case 45: UND ("Graphic Print Color Syntax"); break; + case 46: UND ("Graphic Print Background"); break; + case 47: UND ("Graphic Rotated Print"); break; + case 66: /* UND ("Application keypad"); */ break; + case 67: UND ("Backarrow backspace"); break; + case 69: UND ("Margin mode"); break; + case 80: UND ("Sixel Mode"); break; + case 95: UND ("Do not clear"); break; + case 1000: UND ("Send Mouse"); break; + case 1001: UND ("Hilite Mouse Tracking"); break; + case 1002: UND ("Cell Motion Mouse"); break; + case 1003: UND ("All Motion Mouse"); break; + case 1004: UND ("Focus Events"); break; + case 1005: UND ("UTF-8 Mouse"); break; + case 1006: UND ("SGR Mouse"); break; + case 1007: UND ("Alternate Scroll"); break; + case 1010: UND ("Scroll on output"); break; + case 1011: UND ("Scroll on press"); break; + case 1014: UND ("Fast scroll"); break; + case 1015: UND ("URXVT Mouse"); break; + case 1016: UND ("SGR Mouse"); break; + case 1024: LOG ("Enable/disable focus report"); break; + case 1034: UND ("Meta key"); break; + case 1035: UND ("Alt modifiers"); break; + case 1036: UND ("ESC Meta"); break; + case 1037: UND ("DEL Delete"); break; + case 1039: UND ("ESC Alt"); break; + case 1040: UND ("selection when not highlighted"); break; + case 1041: UND ("Use CLIPBOARD"); break; + case 1042: UND ("Enable Urgency"); break; + case 1043: UND ("Enable raising"); break; + case 1044: UND ("Reuse clipboard"); break; + case 1045: UND ("Extended reverse-wraparound"); break; + case 1046: UND ("Enable Alternate Screen"); break; + case 1047: UND ("Alternate Screen Buffer"); break; + case 1048: UND ("Save cursor"); break; + case 1049: UND ("Save cursor"); break; + case 1050: UND ("Terminfo Fn keys"); break; + case 1051: UND ("Set Sun Fn keys"); break; + case 1052: UND ("HP Fn keys"); break; + case 1053: UND ("SCO Fn keys"); break; + case 1060: UND ("Legacy keyboard emulation"); break; + case 1061: UND ("VT220 keyboard emulation"); break; + case 2001: UND ("Readline mouse 1"); break; + case 2002: UND ("Readline mouse 2"); break; + case 2003: UND ("Readline mouse 2"); break; + case 2004: UND ("Bracketed paste"); break; + case 2005: UND ("readline quoting"); break; + case 2006: UND ("Readline newline paste"); break; + default: UND ("Unknown GR H/L"); break; + } + } + break; + + case 'i': /* Ports */ + if (av[0] == UNDEF) av[0] = 0; + switch (av[0]) { + case 0: UND ("Print screen"); break; + case 1: UND ("Print cursor line"); break; + case 4: UND ("Aux Port Off"); break; + case 5: UND ("Aux Port On"); break; + case 10: UND ("Print dpy"); break; + case 11: UND ("Print all"); break; + default: UND ("Unknown port request"); break; + } + break; + + /* Unused: 'j', 'k'; 'l' is above. */ + + case 'm': /* Select Graphic Rendition */ + if (ac == 0) + av[ac++] = 0; /* No args means "CSI 0m" */ + for (i = 0; i < ac; i++) { + switch (av[i]) { + case UNDEF: + case 0: LOG ("Reset text props"); + st->flags = 0; + break; + case 1: LOG ("Bold"); + st->flags |= TTY_BOLD; + break; + case 2: LOG ("Dim"); + st->flags |= TTY_DIM; + break; + case 3: LOG ("Italic"); + st->flags |= TTY_ITALIC; + break; + case 4: LOG ("Underline"); + st->flags |= TTY_UNDERLINE; + break; + case 5: LOG ("Blink"); + st->flags |= TTY_BLINK; + break; + case 6: LOG ("Blink fast"); + st->flags |= TTY_BLINK; + break; + case 7: LOG ("Invert"); + st->flags |= TTY_INVERSE; + break; + case 8: UND ("Hide"); break; + case 9: UND ("Strike"); break; + + case 10: LOG ("Primary font"); + st->flags &= ~TTY_SYMBOLS; + break; + case 11: LOG ("Alternate font 1"); + st->flags |= TTY_SYMBOLS; + break; + case 12: UND ("Alternate font 2"); break; + case 13: UND ("Alternate font 3"); break; + case 14: UND ("Alternate font 4"); break; + case 15: UND ("Alternate font 5"); break; + case 16: UND ("Alternate font 6"); break; + case 17: UND ("Alternate font 7"); break; + case 18: UND ("Alternate font 8"); break; + case 19: UND ("Alternate font 9"); break; + case 20: UND ("Fraktur font"); break; + case 21: LOG ("Doubly underlined"); + st->flags |= TTY_UNDERLINE; + break; + case 22: LOG ("Not dim"); + st->flags &= ~TTY_DIM; + break; + case 23: LOG ("Not italic"); + st->flags &= ~(TTY_ITALIC|TTY_BOLD); + break; + case 24: LOG ("Not underlined"); + st->flags &= ~TTY_UNDERLINE; + break; + case 25: LOG ("No blink"); + st->flags &= ~TTY_BLINK; + break; + case 26: LOG ("Proportional spacing"); break; + case 27: LOG ("Not reversed"); + st->flags &= ~TTY_INVERSE; + break; + case 28: LOG ("Reveal"); break; + case 29: LOG ("Not strike"); break; + + case 30: LOG ("Set foreground color 1"); + set_color (tty, True, 0); break; + case 31: LOG ("Set foreground color 2"); + set_color (tty, True, 1); break; + case 32: LOG ("Set foreground color 3"); + set_color (tty, True, 2); break; + case 33: LOG ("Set foreground color 4"); + set_color (tty, True, 3); break; + case 34: LOG ("Set foreground color 5"); + set_color (tty, True, 4); break; + case 35: LOG ("Set foreground color 6"); + set_color (tty, True, 5); break; + case 36: LOG ("Set foreground color 7"); + set_color (tty, True, 6); break; + case 37: LOG ("Set foreground color 8"); + set_color (tty, True, 7); break; + + case 38: LOG ("Set foreground color N"); + if (av[i] == 5) + set_color (tty, True, av[i+1]); /* 5;N */ + else if (av[i] == 2) + { + st->fg.r = av[i+1]; /* 2;R;G;B */ + st->fg.g = av[i+2]; + st->fg.b = av[i+3]; + } + i = 999; /* stop processing */ + break; + + case 39: LOG ("Default foreground color"); + set_color (tty, True, 0); break; + + case 40: LOG ("Set background color 1"); + set_color (tty, False, 0); break; + case 41: LOG ("Set background color 2"); + set_color (tty, False, 1); break; + case 42: LOG ("Set background color 3"); + set_color (tty, False, 2); break; + case 43: LOG ("Set background color 4"); + set_color (tty, False, 3); break; + case 44: LOG ("Set background color 5"); + set_color (tty, False, 4); break; + case 45: LOG ("Set background color 6"); + set_color (tty, False, 5); break; + case 46: LOG ("Set background color 7"); + set_color (tty, False, 6); break; + case 47: LOG ("Set background color 8"); + set_color (tty, False, 7); break; + + case 48: LOG ("Set background color N"); + if (av[i] == 5) + set_color (tty, False, av[i+1]); /* 5;N */ + else if (av[i] == 2) + { + st->bg.r = av[i+1]; /* 2;R;G;B */ + st->bg.g = av[i+2]; + st->bg.b = av[i+3]; + } + i = 999; /* stop processing */ + break; + + case 49: LOG ("Default background color"); + set_color (tty, False, 0); break; + + case 50: UND ("Fixed width"); break; + case 51: UND ("Framed"); break; + case 52: UND ("Encircled"); break; + case 53: UND ("Overlined"); break; + case 54: UND ("Not framed"); break; + case 55: UND ("Not overlined"); break; + case 58: UND ("Set underline color"); break; + /* 5;n or 2;r;g;b */ + case 59: UND ("Default underline color"); break; + case 60: UND ("Ideogram underline"); break; + case 61: UND ("Ideogram double underline"); break; + case 62: UND ("Ideogram overline"); break; + case 63: UND ("Ideogram double overline"); break; + case 64: UND ("Ideogram stress marking"); break; + case 65: UND ("No ideogram"); break; + case 73: UND ("Superscript"); break; + case 74: UND ("Subscript"); break; + case 75: UND ("Not super/sub"); break; + default: UND ("Unknown"); break; + break; + } + } + break; + + case 'n': /* Reports */ + switch (av[0]) { + case 5: LOG ("Report status"); + if (tty->tty_send) + { /* Terminal ok */ + const char *s = CSI "0n"; + (*tty->tty_send) (tty->closure, s); + } + break; + case 6: LOG ("Report cursor position"); + if (tty->tty_send) + { + char buf[40]; + sprintf (buf, CSI "%d;%dR", tty->y+1, tty->x+1); + (*tty->tty_send) (tty->closure, buf); + } + break; + default: UND ("Unknown report request"); break; + break; + } + break; + + /* No 'o' */ + + case 'p': UND ("Pointer mode"); break; + case 'q': UND ("LEDs"); break; + + case 'r': LOG ("Scroll Region"); + if (av[0] == UNDEF) av[0] = 1; + if (av[1] == UNDEF) av[1] = tty->height; + /* Top and bottom lines, 1-based, inclusive. + So "3;3" means a single line at y=2. */ + st->scroll.y1 = av[0] - 1; + st->scroll.y2 = av[1]; + tty->x = 0; + tty->y = st->scroll.y1; + st->lcf = False; + break; + + case 's': LOG ("Save Current Cursor Position"); + st->saved.flags = st->flags; + st->saved.lcf = st->lcf; + st->saved.x = tty->x; + st->saved.y = tty->y; + break; + + case 't': UND ("Window manip"); break; + + case 'u': LOG ("Restore Saved Cursor Position"); + st->flags = st->saved.flags; + st->lcf = st->saved.lcf; + tty->x = st->saved.x; + tty->y = st->saved.y; + /* Set lcf to False here? */ + break; + + case 'v': UND ("Display extent"); break; + case 'w': UND ("State report"); break; + case 'x': UND ("Param report"); break; + + case 'y': /* Tests */ + switch (av[0]) { + case 2: + if (av[1] == UNDEF) av[1] = 0; + switch (av[1]) { + case 0: LOG ("Reset"); + ansi_tty_reset (tty); + break; + case 1: LOG ("Self-test"); + if (tty->tty_send) + { + char buf[40]; + sprintf (buf, CSI "%dn", 0); /* Ready */ + (*tty->tty_send) (tty->closure, buf); + } + break; + case 2: UND ("Data loopback test"); break; + case 4: UND ("EIA modem test"); break; + case 8: UND ("Repeat tests forever"); break; + default: UND ("Unknown test"); break; + } + break; + default: UND ("Unknown y"); break; + break; + } + break; + + case 'z': UND ("Erase rect"); break; + case '{': UND ("Selective erase"); break; + case '|': UND ("Cols per page"); break; + case '}': UND ("Insert cols"); break; + case '~': UND ("Delete cols"); break; + default: UND ("Unknown"); break; + } + } + + + /********************************************************************* Fe */ + + + else if (st->idx == 2 && /* Fe escape sequence */ + st->buf[0] == ESC && + c >= 0x40 && /* @A-Z[\]^_ */ + c <= 0x5F) + { + kind = "Fe"; + done = True; + + switch (c) { /* These commands await ST */ + case 'P': /* Device Control String */ + case ']': /* System Command */ + case 'X': /* Start of String */ + case '^': /* Privacy Message */ + case '_': /* Application Program */ + st->awaiting_st = True; + break; + case '\\': /* ST: String Terminator */ + st->awaiting_st = False; + break; + case 'N': UND ("Single Shift Two"); break; + case 'O': UND ("Single Shift Three"); break; + + case '[': /* CSI: Control Sequence Introducer */ + done = False; + break; + + case 'A': LOG ("VT52 Cursor up"); + tty->y--; + break; + case 'B': LOG ("VT52 Cursor down"); + tty->y++; + scrolled_p = True; + /* Set lcf to False here? */ + break; + case 'C': LOG ("VT52 Cursor right"); + tty->x++; + scrolled_p = True; + /* Set lcf to False here? */ + break; + case 'D': LOG ("Cursor down"); + goto DO_LF; /* VT52 Cursor left! */ + break; + case 'E': LOG ("Next line"); + tty->x = 0; + goto DO_LF; + break; + case 'F': LOG ("VT52 Graphics mode"); + st->flags |= TTY_SYMBOLS; + break; + case 'G': LOG ("VT52 Exit graphics"); + st->flags &= ~TTY_SYMBOLS; + break; + case 'H': LOG ("Set tab"); + st->tabs[tty->x] = 1; + break; + + case 'I': /* VT52 */ + case 'M': + st->lcf = False; + tty->y--; + if (tty->y < st->scroll.y1) + { + LOG ("Rev LF scroll"); + tty->y = st->scroll.y1; + tty_scroll (tty, -1); + scrolled_p = True; + } + else + LOG ("Rev LF"); + break; + + case 'J': LOG ("VT52 Erase to EOS"); + tty_erase (tty, + tty->x, tty->x, + tty->width-1, tty->height-1); + break; + case 'K': LOG ("VT52 Erase to EOL"); + tty_erase (tty, + tty->x, tty->y, + tty->width-1, tty->y); + break; + + case 'Y': UND ("VT52 Direct cursor"); + /* 4-byte sequence: "ESC Y y x" where x and y are \037 + N. + But the rest of the Fe commands are 2 bytes. */ + break; + + case 'Z': LOG ("VT52 Identify"); + if (tty->tty_send) + { + char buf[40]; + sprintf (buf, "%c%c%c", ESC, '/', 'Z'); + (*tty->tty_send) (tty->closure, buf); + } + break; + + default: UND ("Unknown"); break; + } + } + + + /********************************************************************* Fs */ + + + else if (st->idx == 2 && /* Fs escape sequence */ + st->buf[0] == ESC && + c >= 0x60 && /* `a-z{|}~ */ + c <= 0x7E) + { + kind = "Fs"; + done = True; + + switch (c) { + case '`': UND ("Disable manual input"); break; + case 'a': UND ("Interrupt"); break; + case 'b': UND ("Enable manual input"); break; + case 'c': LOG ("Full Reset"); + ansi_tty_reset (tty); + break; + case 'd': UND ("Coding method delimiter");break; + case 'l': UND ("Memory Lock"); break; + case 'm': UND ("Memory Unlock"); break; + case 'n': UND ("G2 as GL"); break; + case 'o': UND ("G3 as GL"); break; + case '|': UND ("G3 as GR"); break; + case '~': UND ("G1 as GR"); break; + case '}': UND ("G2 as GR"); break; + default: UND ("Unknown"); break; + } + } + + else if (st->idx > 0 && + st->buf[0] == ESC) + { + /* An ESC followed by a character that matched none of the above. + We assume it is an unknown 2-byte sequence, which may not be true. + */ + kind = "ESC"; + done = True; + UND ("Unrecognized"); + } + + + /******************************************************************* UTF8 */ + + /* Assemble UTF-8 multi-byte sequences into a 32 bit Unicode character. */ + + + else if (st->unicrud > 0) /* Expect N more bytes of Unicode */ + { + kind = "UC"; + st->unicrud--; + if (st->unicrud == 0) + { + /* Finished: replace c with the unichar. */ + c = 0; + utf8_decode ((unsigned char *) st->buf, st->idx, &c); + done = True; + goto SELF_INSERT; + } + } + else if ((c & 0xE0) == 0xC0) /* 110xxxxx: 11 bits, 2 bytes */ + { + kind = "UC2"; + st->unicrud = 1; + } + else if ((c & 0xF0) == 0xE0) /* 1110xxxx: 16 bits, 3 bytes */ + { + kind = "UC3"; + st->unicrud = 2; + } + else if ((c & 0xF8) == 0xF0) /* 11110xxx: 21 bits, 4 bytes */ + { + kind = "UC4"; + st->unicrud = 3; + } + else if ((c & 0xFC) == 0xF8) /* 111110xx: 26 bits, 5 bytes */ + { + kind = "UC5"; + st->unicrud = 4; + } + else if ((c & 0xFE) == 0xFC) /* 1111110x: 31 bits, 6 bytes */ + { + kind = "UC6"; + st->unicrud = 5; + } + + + /******************************************************************** Co */ + + + else /* Co control codes: single chars. */ + { + SELF_INSERT: + kind = "Co"; + done = True; + + SELF_INSERT_INTERLUDE: + + switch (c) { + case 0: /* NOOP */ + break; + + case 0x07: /* BEL */ + tty_log_c (tty, c); + break; + + case 0x08: /* BS */ + tty_log_c (tty, c); + if (tty->x > 0) + tty->x--; + st->lcf = False; + break; + + case 0x09: /* HT: TAB */ + { + /* Tabs are motion and do not alter what's under them. */ + tty_log_c (tty, c); + tty->x++; + while (tty->x < tty->width && !st->tabs[tty->x]) + tty->x++; + st->lcf = False; + } + break; + + case 0x0A: /* LF */ + case 0x0B: /* VT */ + case 0x0C: /* FF */ + tty_log_c (tty, c); + DO_LF: + if (st->linefeed_p) + tty->x = 0; + tty->y++; + st->lcf = False; + scrolled_p = True; + if (tty->y >= st->scroll.y2) + { + int n = tty->y - st->scroll.y2 + 1; + ac = 0; + av[ac++] = n; + LOG ("Scroll"); + tty_scroll (tty, n); + tty->y = st->scroll.y2 - 1; + } + break; + + case 0x1A: /* SUB */ + tty_log_c (tty, c); + st->lcf = False; + break; + + case 0x0D: /* CR */ + tty_log_c (tty, c); + tty->x = 0; + st->lcf = False; + break; + + case 0x0E: /* SO */ + tty_log_c (tty, 0); + LOG ("SO font G1"); + if (st->g1 & TTY_SYMBOLS) + st->flags |= TTY_SYMBOLS; + else + st->flags &= ~TTY_SYMBOLS; + break; + + case 0x0F: /* SI */ + tty_log_c (tty, 0); + LOG ("SI font G0"); + if (st->g0 & TTY_SYMBOLS) + st->flags |= TTY_SYMBOLS; + else + st->flags &= ~TTY_SYMBOLS; + break; + + default: /* Insert */ + tty_log_c (tty, c); + if (c >= ' ') + { + tty_char *ch; + if (tty->x >= tty->width - 1) + { + tty->x = tty->width - 1; + if (st->lcf == False) + st->lcf = True; + else + { + st->lcf = False; + if (tty->state->auto_wrap_p) + { + tty->x = 0; + tty->y++; + if (tty->y >= st->scroll.y2) + { + int n = tty->y - st->scroll.y2 + 1; + ac = 0; + av[ac++] = n; + LOG ("Scroll wrap"); + tty_scroll (tty, n); + tty->y = st->scroll.y2 - 1; + scrolled_p = True; + } + else if (tty->debug_p > 2) + LOG ("Wrap"); + } + } + } + + if (tty->x >= tty->width) abort(); + if (tty->y >= tty->height) abort(); + + ch = &tty->grid[tty->y * tty->width + tty->x]; + ch->c = c; + ch->flags = st->flags; + ch->fg = st->fg; + ch->bg = st->bg; + tty->x++; + } + break; + } + } + + if (tty->x < 0) tty->x = 0; + if (tty->x >= tty->width) tty->x = tty->width - 1; + + /* Scrolling commands, or insertions that changed Y, clip the cursor to + the scrolling region. But cursor-positioning commands do not. */ + if (scrolled_p) + { + if (tty->y < st->scroll.y1) tty->y = st->scroll.y1; + if (tty->y >= st->scroll.y2) tty->y = st->scroll.y2 - 1; + } + else + { + if (tty->y < 0) tty->y = 0; + if (tty->y >= tty->height) tty->y = tty->height - 1; + } + + if (done) + { + st->idx = 0; + st->buf[0] = 0; + } +} + diff --git a/hacks/ansi-tty.h b/hacks/ansi-tty.h new file mode 100644 index 00000000..ff836e17 --- /dev/null +++ b/hacks/ansi-tty.h @@ -0,0 +1,63 @@ +/* xscreensaver, Copyright © 2025 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifndef __XSCREENSAVER_ANSI_TTY_H__ +#define __XSCREENSAVER_ANSI_TTY_H__ + +typedef enum { + TTY_BOLD = 1, + TTY_ITALIC = 2, + TTY_INVERSE = 4, + TTY_DIM = 8, + TTY_UNDERLINE = 16, + TTY_BLINK = 32, + TTY_SYMBOLS = 64, +} tty_flag; + +typedef struct { unsigned char r, g, b; } tty_color; + +typedef struct { + unsigned long c; /* Unicode */ + tty_flag flags; /* Bitmask */ + tty_color fg, bg; +} tty_char; + +typedef void (*tty_send_fn) (void *closure, const char *text); + +typedef struct tty_state tty_state; +typedef struct { /* Do not change these: */ + + int x, y; /* Cursor position */ + int width, height; /* Screen size */ + int inverse_p; /* Flip the sense of TTY_INVERSE */ + tty_char *grid; /* Characters */ + tty_state *state; /* Internal state */ + + /* You can change these: */ + + tty_send_fn tty_send; /* Type characters to upstream */ + void *closure; + tty_color cmap[16][2]; /* Default indexed colors */ + + int debug_p; /* 1: log errors to stderr + 2: and all commands + 3: and all text + 4: log to /tmp */ +} ansi_tty; + +extern ansi_tty *ansi_tty_init (int w, int h); +extern void ansi_tty_resize (ansi_tty *, int w, int h); +extern void ansi_tty_print (ansi_tty *, unsigned long c); +extern void ansi_tty_free (ansi_tty *); + +extern const unsigned long ansi_graphics_unicode[256]; + +#endif /* __XSCREENSAVER_ANSI_TTY_H__ */ diff --git a/hacks/apple2-main.c b/hacks/apple2-main.c index a87ea1a1..ae517a23 100644 --- a/hacks/apple2-main.c +++ b/hacks/apple2-main.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1998-2021 Jamie Zawinski +/* xscreensaver, Copyright © 1998-2025 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -16,6 +16,7 @@ #include "screenhack.h" #include "apple2.h" #include "textclient.h" +#include "ansi-tty.h" #include "utf8wc.h" #include @@ -778,19 +779,24 @@ static void slideshow_controller(apple2_sim_t *sim, int *stepno, #define NPAR 16 +#define COUNTDOWN_BANNER "intermission " +#define COUNTDOWN_DURATION 18*60+30 +#undef COUNTDOWN_BANNER + struct terminal_controller_data { Display *dpy; char curword[256]; unsigned char lastc; double last_emit_time; + time_t launch_time; text_data *tc; + ansi_tty *tty; int escstate; int csiparam[NPAR]; int curparam; int cursor_x, cursor_y; int saved_x, saved_y; - int unicruds; char unicrud[7]; union { struct { unsigned int bold : 1; @@ -803,6 +809,8 @@ struct terminal_controller_data { }; +static void a2_tty_send (void *, const char *); + /* The structure of closure linkage throughout this code is so amazingly baroque that I can't get to the 'struct state' from where I need it. */ @@ -817,6 +825,9 @@ terminal_closegen(struct terminal_controller_data *mine) textclient_close (mine->tc); mine->tc = 0; } + + if (mine->tty) + ansi_tty_free (mine->tty); } static int @@ -845,11 +856,55 @@ terminal_keypress_handler (Display *dpy, XEvent *event, void *data) (struct terminal_controller_data *) data; mine->dpy = dpy; if (event->xany.type == KeyPress && mine->tc) - return textclient_putc (mine->tc, &event->xkey); + return textclient_putc_event (mine->tc, &event->xkey); return 0; } +#ifdef COUNTDOWN_BANNER +static void +a2_draw_banner (apple2_state_t *st, struct terminal_controller_data *mine) +{ + int x, y; + int w = 40; + int h = 3; + char buf[41], *s; + struct timeval tv; + double t; + + for (y = 0; y < h; y++) + for (x = 0; x < w; x++) + st->textlines[y][x] = ' ' | 0xC0; + +# ifdef GETTIMEOFDAY_TWO_ARGS + gettimeofday (&tv, NULL); +# else + gettimeofday (&tv); +# endif + + t = ((mine->launch_time + COUNTDOWN_DURATION) - + (tv.tv_sec + ((double) tv.tv_usec * 0.000001))); + if (t < 0) t = 0; + sprintf (buf, "%.30s %d:%02d:%02d.%1d", + COUNTDOWN_BANNER, + (int) (t/60/60), + (int) (t/60) % 60, + (int) t % 60, + (int) (t * 10) % 10); + x = (w - strlen (buf)) / 2; + y = 0; + s = buf; + while (*s && x < w) { + char c = *s++; + if (c >= 'a' && c <= 'z') c &= 0xDF; + c |= 0xC0; + st->textlines[y][x] = c; + x++; + } +} +#endif /* COUNTDOWN_BANNER */ + + static void a2_ascii_printc (apple2_state_t *st, unsigned char c, Bool bold_p, Bool blink_p, Bool rev_p, @@ -867,7 +922,9 @@ a2_ascii_printc (apple2_state_t *st, unsigned char c, } else if (c >= 'A' && c <= 'Z') /* invert upper-case chars */ { +# ifndef COUNTDOWN_BANNER c |= 0x80; +# endif } if (bold_p) c |= 0xc0; @@ -886,434 +943,81 @@ a2_vt100_printc (apple2_sim_t *sim, struct terminal_controller_data *state, unsigned char c) { apple2_state_t *st=sim->st; - int cols = SCREEN_COLS; - int rows = SCREEN_ROWS; - - int i; - int start, end; + int w = SCREEN_COLS; + int h = SCREEN_ROWS; + int x, y; + ansi_tty *tty = state->tty; + ansi_tty_print (tty, c); - /* Mostly duplicated in phosphor.c */ + /* We could optimize this to not re-draw characters that haven't changed, + but it seems plenty fast enough. */ - switch (state->escstate) - { - case 0: - switch (c) - { - case 7: /* BEL */ - /* Dummy case - we don't want the screensaver to beep */ - /* #### But maybe this should flash the screen? */ - break; - case 8: /* BS */ - if (state->cursor_x > 0) - state->cursor_x--; - break; - case 9: /* HT */ - if (state->cursor_x < cols - 8) - { - state->cursor_x = (state->cursor_x & ~7) + 8; - } - else - { - state->cursor_x = 0; - if (state->cursor_y < rows - 1) - state->cursor_y++; - else - a2_scroll (st); - } - break; - case 10: /* LF */ -# ifndef HAVE_FORKPTY - state->cursor_x = 0; /* No ptys on iPhone; assume CRLF. */ -# endif - case 11: /* VT */ - case 12: /* FF */ - if (state->cursor_y < rows - 1) - state->cursor_y++; - else - a2_scroll (st); - break; - case 13: /* CR */ - state->cursor_x = 0; - break; - case 14: /* SO */ - case 15: /* SI */ - /* Dummy case - there is one and only one font. */ - break; - case 24: /* CAN */ - case 26: /* SUB */ - /* Dummy case - these interrupt escape sequences, so - they don't do anything in this state */ - break; - case 27: /* ESC */ - state->escstate = 1; - break; - case 127: /* DEL */ - /* Dummy case - this is supposed to be ignored */ - break; - case 155: /* CSI */ - state->escstate = 2; - for(i = 0; i < NPAR; i++) - state->csiparam[i] = 0; - state->curparam = 0; - break; - default: - - /* states 102-106 are for UTF-8 decoding */ - - if ((c & 0xE0) == 0xC0) { /* 110xxxxx - 11 bits, 2 bytes */ - state->unicruds = 1; - state->unicrud[0] = c; - state->escstate = 102; - break; - } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx - 16 bits, 3 bytes */ - state->unicruds = 1; - state->unicrud[0] = c; - state->escstate = 103; - break; - } else if ((c & 0xF8) == 0xF0) { /* 11110xxx - 21 bits, 4 bytes */ - state->unicruds = 1; - state->unicrud[0] = c; - state->escstate = 104; - break; - } else if ((c & 0xFC) == 0xF8) { /* 111110xx - 26 bits, 5 bytes */ - state->unicruds = 1; - state->unicrud[0] = c; - state->escstate = 105; - break; - } else if ((c & 0xFE) == 0xFC) { /* 1111110x - 31 bits, 6 bytes */ - state->unicruds = 1; - state->unicrud[0] = c; - state->escstate = 106; - break; + for (y = 0; y < h; y++) + for (x = 0; x < w; x++) + { + tty_char *tc = &tty->grid [tty->width * y + x]; + unsigned char ascii = 0; + tty_flag flag = tc->flags; + int inv_p = flag & (TTY_INVERSE | TTY_BOLD); + if (tty->inverse_p) inv_p = !inv_p; + + if (tc->c <= 128) + ascii = tc->c; + else + { + /* Convert non-ASCII Unicode to closest ASCII. */ + char utf8[10]; + int L = utf8_encode (tc->c, utf8, sizeof(utf8)-1); + utf8[L] = 0; + ascii = '?'; + if (L) + { + char *s = utf8_to_latin1 (utf8, True); + if (s) + { + ascii = s[0]; + free (s); + } + } } - PRINT: - - /* If the cursor is in column 39 and we print a character, then - that character shows up in column 39, and the cursor is no longer - visible on the screen (it's in "column 40".) If another character - is printed, then that character shows up in column 0, and the - cursor moves to column 1. + if (! ascii) ascii = ' '; + + a2_goto (st, y, x); + + if (flag & TTY_SYMBOLS) /* Convert to the nearest ASCII */ + switch (ascii) { + case 0x60: ascii = '*'; /* ◆ */ flag &= ~TTY_SYMBOLS; break; + case 0x6A: ascii = 'J'; /* ┘ */ flag &= ~TTY_SYMBOLS; break; + case 0x6B: ascii = 'T'; /* ┐ */ flag &= ~TTY_SYMBOLS; break; + case 0x6C: ascii = 'r'; /* ┌ */ flag &= ~TTY_SYMBOLS; break; + case 0x6D: ascii = 'L'; /* └ */ flag &= ~TTY_SYMBOLS; break; + case 0x6E: ascii = '+'; /* ┼ */ flag &= ~TTY_SYMBOLS; break; + case 0x6F: ascii = '-'; /* ⎺ */ flag &= ~TTY_SYMBOLS; break; + case 0x70: ascii = '-'; /* ⎻ */ flag &= ~TTY_SYMBOLS; break; + case 0x71: ascii = '='; /* ─ */ flag &= ~TTY_SYMBOLS; break; + case 0x72: ascii = '_'; /* ⎼ */ flag &= ~TTY_SYMBOLS; break; + case 0x73: ascii = '_'; /* ⎽ */ flag &= ~TTY_SYMBOLS; break; + case 0x74: ascii = 'F'; /* ├ */ flag &= ~TTY_SYMBOLS; break; + case 0x75: ascii = '+'; /* ┤ */ flag &= ~TTY_SYMBOLS; break; + case 0x76: ascii = '+'; /* ┴ */ flag &= ~TTY_SYMBOLS; break; + case 0x77: ascii = 'T'; /* ┬ */ flag &= ~TTY_SYMBOLS; break; + case 0x78: ascii = '#'; /* │ */ flag &= ~TTY_SYMBOLS; break; + } - This is empirically what xterm and gnome-terminal do, so that must - be the right thing. (In xterm, the cursor vanishes, whereas; in - gnome-terminal, the cursor overprints the character in col 39.) - */ - if (state->cursor_x >= cols) - { - state->cursor_x = 0; - if (state->cursor_y >= rows - 1) - a2_scroll (st); - else - state->cursor_y++; - } - a2_goto(st, state->cursor_y, state->cursor_x); /* clips range */ - a2_ascii_printc (st, c, - state->termattrib.bf.bold, - state->termattrib.bf.blink, - state->termattrib.bf.rev, + if (flag & TTY_SYMBOLS) + /* Draw unknown symbol font characters as a box. */ + a2_ascii_printc (st, ' ', 0, 0, !inv_p, False); + else + a2_ascii_printc (st, ascii, + 0, + flag & TTY_BLINK, + inv_p, False); - state->cursor_x++; - - break; - } - break; - case 1: - switch (c) - { - case 24: /* CAN */ - case 26: /* SUB */ - state->escstate = 0; - break; - case 'c': /* Reset */ - a2_cls(st); - state->escstate = 0; - break; - case 'D': /* Linefeed */ - if (state->cursor_y < rows - 1) - state->cursor_y++; - else - a2_scroll (st); - state->escstate = 0; - break; - case 'E': /* Newline */ - state->cursor_x = 0; - state->escstate = 0; - break; - case 'M': /* Reverse newline */ - if (state->cursor_y > 0) - state->cursor_y--; - state->escstate = 0; - break; - case '7': /* Save state */ - state->saved_x = state->cursor_x; - state->saved_y = state->cursor_y; - state->escstate = 0; - break; - case '8': /* Restore state */ - state->cursor_x = state->saved_x; - state->cursor_y = state->saved_y; - state->escstate = 0; - break; - case '[': /* CSI */ - state->escstate = 2; - for(i = 0; i < NPAR; i++) - state->csiparam[i] = 0; - state->curparam = 0; - break; - case '%': /* Select charset */ - /* @: Select default (ISO 646 / ISO 8859-1) - G: Select UTF-8 - 8: Select UTF-8 (obsolete) - - We can just ignore this and always process UTF-8, I think? - We must still catch the last byte, though. - */ - case '(': - case ')': - /* I don't support different fonts either - see above - for SO and SI */ - state->escstate = 3; - break; - default: - /* Escape sequences not supported: - * - * H - Set tab stop - * Z - Terminal identification - * > - Keypad change - * = - Other keypad change - * ] - OS command - */ - state->escstate = 0; - break; - } - break; - case 2: - switch (c) - { - case 24: /* CAN */ - case 26: /* SUB */ - state->escstate = 0; - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (state->curparam < NPAR) - state->csiparam[state->curparam] = - (state->csiparam[state->curparam] * 10) + (c - '0'); - break; - case ';': - state->csiparam[++state->curparam] = 0; - break; - case '[': - state->escstate = 3; - break; - case '@': - for (i = 0; i < state->csiparam[0]; i++) - { - if(++state->cursor_x > cols) - { - state->cursor_x = 0; - if (state->cursor_y < rows - 1) - state->cursor_y++; - else - a2_scroll (st); - } - } - state->escstate = 0; - break; - case 'F': - state->cursor_x = 0; - case 'A': - if (state->csiparam[0] == 0) - state->csiparam[0] = 1; - if ((state->cursor_y -= state->csiparam[0]) < 0) - state->cursor_y = 0; - state->escstate = 0; - break; - case 'E': - state->cursor_x = 0; - case 'e': - case 'B': - if (state->csiparam[0] == 0) - state->csiparam[0] = 1; - if ((state->cursor_y += state->csiparam[0]) >= rows) - state->cursor_y = rows - 1; - state->escstate = 0; - break; - case 'a': - case 'C': - if (state->csiparam[0] == 0) - state->csiparam[0] = 1; - if ((state->cursor_x += state->csiparam[0]) >= cols) - state->cursor_x = cols - 1; - state->escstate = 0; - break; - case 'D': - if (state->csiparam[0] == 0) - state->csiparam[0] = 1; - if ((state->cursor_x -= state->csiparam[0]) < 0) - state->cursor_x = 0; - state->escstate = 0; - break; - case 'd': - if ((state->cursor_y = (state->csiparam[0] - 1)) >= rows) - state->cursor_y = rows - 1; - state->escstate = 0; - break; - case '`': - case 'G': - if ((state->cursor_x = (state->csiparam[0] - 1)) >= cols) - state->cursor_x = cols - 1; - state->escstate = 0; - break; - case 'f': - case 'H': - if ((state->cursor_y = (state->csiparam[0] - 1)) >= rows) - state->cursor_y = rows - 1; - if ((state->cursor_x = (state->csiparam[1] - 1)) >= cols) - state->cursor_x = cols - 1; - if(state->cursor_y < 0) - state->cursor_y = 0; - if(state->cursor_x < 0) - state->cursor_x = 0; - state->escstate = 0; - break; - case 'J': - start = 0; - end = rows * cols; - if (state->csiparam[0] == 0) - start = cols * state->cursor_y + state->cursor_x; - if (state->csiparam[0] == 1) - end = cols * state->cursor_y + state->cursor_x; - - a2_goto(st, state->cursor_y, state->cursor_x); - for (i = start; i < end; i++) - { - a2_ascii_printc(st, ' ', False, False, False, False); - } - state->escstate = 0; - break; - case 'K': - start = 0; - end = cols; - if (state->csiparam[0] == 0) - start = state->cursor_x; - if (state->csiparam[1] == 1) - end = state->cursor_x; - - a2_goto(st, state->cursor_y, state->cursor_x); - for (i = start; i < end; i++) - { - a2_ascii_printc(st, ' ', False, False, False, False); - } - state->escstate = 0; - break; - case 'm': /* Set attributes */ - for (i = 0; i <= state->curparam; i++) - { - switch(state->csiparam[i]) - { - case 0: - state->termattrib.w = 0; - break; - case 1: - state->termattrib.bf.bold = 1; - break; - case 5: - state->termattrib.bf.blink = 1; - break; - case 7: - state->termattrib.bf.rev = 1; - break; - case 21: - case 22: - state->termattrib.bf.bold = 0; - break; - case 25: - state->termattrib.bf.blink = 0; - break; - case 27: - state->termattrib.bf.rev = 0; - break; - } - } - state->escstate = 0; - break; - case 's': /* Save position */ - state->saved_x = state->cursor_x; - state->saved_y = state->cursor_y; - state->escstate = 0; - break; - case 'u': /* Restore position */ - state->cursor_x = state->saved_x; - state->cursor_y = state->saved_y; - state->escstate = 0; - break; - case '?': /* DEC Private modes */ - if ((state->curparam != 0) || (state->csiparam[0] != 0)) - state->escstate = 0; - break; - default: - /* Known unsupported CSIs: - * - * L - Insert blank lines - * M - Delete lines (I don't know what this means...) - * P - Delete characters - * X - Erase characters (difference with P being...?) - * c - Terminal identification - * g - Clear tab stop(s) - * h - Set mode (Mainly due to its complexity and lack of good - docs) - * l - Clear mode - * m - Set mode (Phosphor is, per defenition, green on black) - * n - Status report - * q - Set keyboard LEDs - * r - Set scrolling region (too exhausting - noone uses this, - right?) - */ - state->escstate = 0; - break; - } - break; - case 3: - state->escstate = 0; - break; - - case 102: - case 103: - case 104: - case 105: - case 106: - { - int total = state->escstate - 100; /* see what I did there */ - if (state->unicruds < total) { - /* Buffer more bytes of the UTF-8 sequence */ - state->unicrud[state->unicruds++] = c; - } - - if (state->unicruds >= total) { - /* Done! Convert it to ASCII and print that. */ - char *s; - state->unicrud[state->unicruds] = 0; - s = utf8_to_latin1 ((const char *) state->unicrud, True); - state->unicruds = 0; - state->escstate = 0; - if (s) { - c = s[0]; - free (s); - goto PRINT; - } else { - /* c = 0; */ - } - } } - break; - default: - abort(); - } - a2_goto(st, state->cursor_y, state->cursor_x); + a2_goto (st, tty->y, tty->x); } @@ -1335,19 +1039,26 @@ terminal_controller(apple2_sim_t *sim, int *stepno, double *next_actiontime) sim->controller_data=calloc(sizeof(struct terminal_controller_data),1); mine=(struct terminal_controller_data *) sim->controller_data; mine->dpy = sim->dpy; + if (!mine->launch_time) mine->launch_time = time ((time_t *) 0); mine->fast_p = global_fast_p; switch(*stepno) { case 0: +# ifdef COUNTDOWN_BANNER + if (1) +# else if (random()%2) +# endif st->gr_mode |= A2_GR_FULL; /* Turn on color mode even through it's showing text */ a2_cls(st); +# ifndef COUNTDOWN_BANNER a2_goto(st,0,16); a2_prints(st, "APPLE ]["); a2_goto(st,2,0); +# endif mine->cursor_y = 2; if (! mine->tc) { @@ -1358,6 +1069,12 @@ terminal_controller(apple2_sim_t *sim, int *stepno, double *next_actiontime) 0); } + if (!mine->tty) { + mine->tty = ansi_tty_init (SCREEN_COLS, SCREEN_ROWS); + mine->tty->closure = mine; + mine->tty->tty_send = a2_tty_send; + } + if (! mine->fast_p) *next_actiontime += 4.0; *stepno = 10; @@ -1400,6 +1117,10 @@ terminal_controller(apple2_sim_t *sim, int *stepno, double *next_actiontime) else a2_ascii_printc (st, c, False, False, False, True); } + +# ifdef COUNTDOWN_BANNER + a2_draw_banner (st, mine); +# endif } break; @@ -1411,6 +1132,15 @@ terminal_controller(apple2_sim_t *sim, int *stepno, double *next_actiontime) } } +static void +a2_tty_send (void *closure, const char *text) +{ + struct terminal_controller_data *mine = + (struct terminal_controller_data *) closure; + textclient_puts (mine->tc, text); +} + + struct basic_controller_data { int prog_line; int x,y,k; diff --git a/hacks/barcode.c b/hacks/barcode.c index 29eb6e03..c42a74dc 100644 --- a/hacks/barcode.c +++ b/hacks/barcode.c @@ -105,6 +105,7 @@ static const char *words[] = "affluenza", "alertness", "Algeria", + "all your base", "antifa", "anxiety", "aorta", @@ -121,12 +122,14 @@ static const char *words[] = "bells", "belly", "bird flu", + "Bitcorn", "bliss", "bogosity", "boobies", "boobs", "booty", "bread", + "bribe", "brogrammers", "bubba", "burrito", @@ -167,14 +170,17 @@ static const char *words[] = "DNA Lounge", "doberman", "DOOM", + "doom loop", "dot com", "dreams", "drugs", + "Dunning-Krugerrands", "easy", "ebony", "election", "eloquence", "emergency", + "emolument", "eureka", "excommunication", "fat", @@ -196,6 +202,8 @@ static const char *words[] = "goggles", "goobers", "gorilla", + "guillotine", + "H5N1", "halibut", "handmaid", "happiness", @@ -206,6 +214,7 @@ static const char *words[] = "heroin", "heroine", "hope", + "horse paste", "hysteria", "icepick", "identity", @@ -255,10 +264,14 @@ static const char *words[] = "nationalism", "nature", "neuron", + "NFTs", "noise", "nomenclature", + "NULL", + "null island", "nutria", "OBEY", + "ouroboros", "ocelot", "offspring", "overseer", @@ -335,6 +348,7 @@ static const char *words[] = "television", "tenant", "tendril", + "teratoma", "terror", "terrorism", "terrorist", @@ -343,10 +357,12 @@ static const char *words[] = "the unknown", "toast", "topography", + "tribble", "truism", "truthiness", "turgid", "twits", + "undef", "underbrush", "underling", "unguent", @@ -386,6 +402,7 @@ static const char *words[] = "yellow", "yesterday", "your nose", + "Y2038", "Zanzibar", "zeal", "zebra", diff --git a/hacks/bsod.c b/hacks/bsod.c index 37bfb614..653d6a34 100644 --- a/hacks/bsod.c +++ b/hacks/bsod.c @@ -37,6 +37,7 @@ #include "screenhack.h" #include "xft.h" +#include "xftwrap.h" #include "ximage-loader.h" #include "apple2.h" @@ -1898,6 +1899,78 @@ windows_10_update (Display *dpy, Window window) } +static struct bsod_state * +windows_10_recovery (Display *dpy, Window window) +{ + struct bsod_state *bst = + make_bsod_state (dpy, window, "win10r", "Win10r"); + const char *line1 = "Recovery"; + const char *line2 = "It looks like Windows didn't load correctly"; + const char *line3 = "If you'd like to restart and try again, choose " + "\"Restart my PC\" below. Otherwise, choose " + "\"See advanced repair options\" for troubleshooting " + "tools and advanced options. If you don't know which " + "option is right for you, contact someone you " + "trust to help with this."; + const char *line4 = " See advanced repair options "; + const char *line5 = " Restart my PC "; + int line_height = bst->fontA->ascent + bst->fontA->descent; + int line_heightB = bst->fontB->ascent + bst->fontB->descent; + int line_heightC = bst->fontC->ascent + bst->fontC->descent; + int y = line_heightC * 2; + int x, x2, x3; + XGlyphInfo ov; + + XftTextExtentsUtf8 (bst->dpy, bst->fontB, (FcChar8 *) line2, strlen(line2), + &ov); + x = (bst->xgwa.width - (ov.xOff * 1.7)) / 2; + if (x < 10) x = 10; + BSOD_MARGINS (bst, x, x); + + BSOD_WORD_WRAP (bst); + BSOD_FONT (bst, 2); + BSOD_MOVETO (bst, 0, y); + BSOD_TEXT (bst, LEFT, line1); + BSOD_TEXT (bst, LEFT, "\n"); + + BSOD_FONT (bst, 1); + BSOD_TEXT (bst, LEFT, line2); + BSOD_TEXT (bst, LEFT, "\n"); + + BSOD_FONT (bst, 0); + BSOD_TEXT (bst, LEFT, line3); + + XftTextExtentsUtf8 (bst->dpy, bst->font, (FcChar8 *) line5, strlen(line5), + &ov); + x2 = bst->xgwa.width - x - ov.xOff; + + if ( bst->xgwa.width > bst->xgwa.height) + y += line_heightB * 2 + line_height * 7; + else + y += line_heightB * 3 + line_height * 9; + + BSOD_TRUNCATE (bst); + BSOD_MOVETO (bst, x2, y); + BSOD_TEXT (bst, LEFT, line5); + BSOD_RECT (bst, False, x2, y - line_height, ov.xOff, + line_height + bst->fontA->descent * 2); + + XftTextExtentsUtf8 (bst->dpy, bst->font, (FcChar8 *) line4, strlen(line4), + &ov); + x3 = x2 - ov.xOff - line_height; + + BSOD_TRUNCATE (bst); + BSOD_MOVETO (bst, x3, y); + BSOD_TEXT (bst, LEFT, line4); + BSOD_RECT (bst, False, x3, y - line_height, ov.xOff, + line_height + bst->fontA->descent * 2); + + + XClearWindow (dpy, window); + return bst; +} + + static struct bsod_state * windows_10 (Display *dpy, Window window) { @@ -1930,49 +2003,88 @@ windows_10 (Display *dpy, Window window) 0xFF,0xFF,0xFF,0xFF,0xFF,0x01}; Pixmap pixmap; - const char * const lines[] = { - ":(\n", - "\n", - "Your PC ran into a problem and needs to restart. We're just\n", - "collecting some error info, and then we'll restart for you.\n", - "\n", - "\n", - "\n", - "For more information about this issue and\n", - "possible fixes, visit\n", -/* "https://www.jwz.org/xscreensaver\n",*/ - "http://youtu.be/-RjmN9RZyr4\n", - "\n", - "If you call a support person, give them this info:\n", + const char * const lines1[] = { + ":(", + + "\n" + "Your PC ran into a problem and needs to restart. We're just" + " collecting some error info, and then we'll restart for you." + "\n\n\n", + + "\n\n", + + "For more information about this issue and possible fixes, visit\n" + "http://youtu.be/-RjmN9RZyr4\n\n" + "If you call a support person, give them this info:\n" "Stop code CRITICAL_PROCESS_DIED", - }; - int i, y = 0, y0 = 0; - int line_height0 = bst->fontB->ascent; - int line_height1 = bst->fontA->ascent + bst->fontA->descent; - int line_height2 = bst->fontC->ascent + bst->fontC->descent; - int line_height = line_height0; - int top, left0, left; - int stop = 60 + (random() % 39); + }; + const char * const lines2[] = { + "-\\_(:/)_/-", /* ¯\\_(ツ)_/¯ BSOD_TEXT() does not support UTF-8. */ - if (!(random() % 7)) - return windows_10_update (dpy, window); + "\n" + "Your PC ran into a ClownStrike and needs to restart 15 or more times." + "\n\n\n", + + "\n\n", + + "For more information about this issue and possible fixes, visit\n" + "http://youtu.be/-RjmN9RZyr4\n\n" + "If you call a support person, give them this info:\n" + "Stop code COMPLIANCE_LINE_ITEM_OK", + }; + const char * const lines3[] = { + "x__x", + + "\n" + "This place is a message... " + "and part of a system of messages... " + "pay attention to it! " + "\n\n" + "Sending this message was important to us. " + "We considered ourselves to be a powerful culture." + "\n\n", + + "\nThis place is not a place of honor... " + "no highly esteemed deed is commemorated here... " + "nothing valued is here. " + "\n\n" + "What is here was dangerous and repulsive to us. " + "This message is a warning about danger. " + "\n", + + "The danger is in a particular location... " + "it increases towards a center... " + "the center of danger is here... " + "of a particular size and shape, and below us. " + "\n\n" + "The danger is still present, in your time, as it was in ours. " + "The danger is to the body, and it can kill. " + "\n\n" + "This place is best shunned and left uninhabited." + }; + int i, y = 0; + int top, left0, left, right, y1; + Bool clownp = !(random() % 10); + Bool honorp = !clownp && !(random() % 20); + const char * const * lines = (clownp ? lines2 : honorp ? lines3 : lines1); + int stop = 60 + (random() % 39) + (clownp ? 1300 : 0); + if (!(random() % 4)) + return windows_10_recovery (dpy, window); - line_height1 *= 1.3; - line_height2 *= 1.5; + if (!(random() % 14)) + return windows_10_update (dpy, window); - top = ((bst->xgwa.height - bst->yoff - - (line_height0 * 1 + - line_height1 * 6 + - line_height2 * 6)) - / 2); + top = (bst->xgwa.height > 800 ? bst->fontB->ascent : 0); { XGlyphInfo ov; - const char *s = lines[2]; - + const char *s = lines1[1]; XftTextExtentsUtf8 (bst->dpy, bst->font, (FcChar8 *) s, strlen(s), &ov); - left = left0 = (bst->xgwa.width - ov.xOff) / 2; + left = (bst->xgwa.width - (ov.xOff * 0.55)) / 2; + if (left < 10) left = 10; + left0 = right = left; + BSOD_MARGINS (bst, left, right); } pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) qr_bits, @@ -1993,39 +2105,59 @@ windows_10 (Display *dpy, Window window) bst->pixmap = pixmap; y = top; - line_height = line_height0; BSOD_FONT (bst, 1); - for (i = 0; i < countof(lines); i++) + for (i = 0; i < countof(lines1); i++) { - BSOD_MOVETO (bst, left, y); - BSOD_TEXT (bst, LEFT, lines[i]); - y += line_height; + int oy = y; + int fid = (i == 0 ? 1 : i >= 3 ? 2 : 0); + XftFont *font = (fid == 0 ? bst->font : + fid == 1 ? bst->fontB : bst->fontC); + char *line; + XGlyphInfo ov; + + line = xft_word_wrap (dpy, font, lines[i], + bst->xgwa.width - left - right); + XftTextExtentsUtf8_multi (dpy, font, (FcChar8 *) line, strlen(line), + &ov); + + BSOD_MOVETO (bst, left, y + font->ascent); + BSOD_FONT (bst, fid); + BSOD_TEXT (bst, LEFT, line); + + free (line); + line = 0; + y += ov.height + font->descent; + if (i == 0) { - BSOD_FONT (bst, 0); - line_height = line_height1; + BSOD_MOVETO (bst, left, y); } - else if (i == 4) + else if (i == 1) { - y0 = y; - y += line_height / 2; - BSOD_PIXMAP (bst, 0, 0, qr_width, qr_height, left, y + line_height1); - BSOD_FONT (bst, 2); - line_height = line_height2; - left += qr_width + line_height2 / 2; -# ifdef HAVE_MOBILE - y -= 14; -# endif +// y += font->ascent + font->descent; + y1 = y; +// y += font->ascent + font->descent; + } + else if (i == 2) + { + left += qr_width + font->ascent / 2; + if (bst->xgwa.width > bst->xgwa.height) + right += qr_width * 1.8; + BSOD_MARGINS (bst, left, right); + } + else if (i == 3) + { + BSOD_PIXMAP (bst, 0, 0, qr_width, qr_height, left0, oy); } } - left = left0; + BSOD_MARGINS (bst, left0, 0); BSOD_FONT (bst, 0); for (i = 0; i <= stop; i++) { char buf[100]; sprintf (buf, "%d%% complete", i); - BSOD_MOVETO (bst, left, y0); + BSOD_MOVETO (bst, left0, y1); BSOD_TEXT (bst, LEFT, buf); BSOD_PAUSE (bst, 85000); } @@ -2672,6 +2804,167 @@ windows_ransomware (Display *dpy, Window window) } +static struct bsod_state * +bitlocker (Display *dpy, Window window) +{ + struct bsod_state *bst = + make_bsod_state (dpy, window, "bitlocker", "Bitlocker"); + int top = bst->fontB->ascent + bst->fontB->descent; + int left = top * 2; + int right = left + bst->fontB->ascent * 22; + const char *bottom = ("Press Enter to reboot and try again\n" + "Press ESC for BitLocker recovery"); + int which = random() % 5; + + if (right > bst->xgwa.width) right = bst->xgwa.width; + BSOD_MARGINS (bst, left, bst->xgwa.width - right); + BSOD_WORD_WRAP (bst); + BSOD_FONT (bst, 1); + BSOD_MOVETO (bst, 0, top * 2); + + switch (which) { + case 0: + BSOD_TEXT (bst, LEFT, "BitLocker\n\n"); + BSOD_FONT (bst, 0); + BSOD_TEXT (bst, LEFT, + "Plug in the USB drive that has the BitLocker key\n"); + break; + + case 1: + BSOD_TEXT (bst, LEFT, "BitLocker recovery\n\n"); + BSOD_FONT (bst, 0); + BSOD_TEXT (bst, LEFT, + "To recover this drive, plug in the USB drive that has " + "the BitLocker recovery key\n\n"); + BSOD_FONT (bst, 2); + BSOD_TEXT (bst, LEFT, + "Bitlocker needs your recovery key to unlock your drive " + "because Secure Boot policy has unexpectedly changed.\n" + "For more information on how to retrieve this key, go to\n" + "https://www.jwz.org/xscreensaver/ from another PC " + "or mobile device."); + bottom = ("Press Enter to reboot and try again\n" + "Press Esc or the Windows key for more recovery options"); + break; + case 2: + BSOD_TEXT (bst, LEFT, "BitLocker\n\n"); + BSOD_FONT (bst, 0); + BSOD_TEXT (bst, LEFT, + "Enter the PIN to unlock this drive\n"); + BSOD_INVERT (bst); + BSOD_TRUNCATE (bst); + BSOD_TEXT (bst, LEFT, + " " + " "); + BSOD_INVERT (bst); + BSOD_WORD_WRAP (bst); + BSOD_TEXT (bst, LEFT, + "\n\n\n" + "Use the number keys or function keys F1-F10 " + "(use F10 for 0)." + "\n\n\n" + "Press the Insert key to see the PIN as you type."); + break; + + case 3: + BSOD_TEXT (bst, LEFT, "BitLocker recovery\n\n"); + BSOD_FONT (bst, 0); + BSOD_TEXT (bst, LEFT, + "Enter the recovery key for this drive\n"); + BSOD_INVERT (bst); + BSOD_TRUNCATE (bst); + BSOD_TEXT (bst, LEFT, + " " + " "); + BSOD_INVERT (bst); + BSOD_WORD_WRAP (bst); + + BSOD_FONT (bst, 2); + BSOD_TEXT (bst, LEFT, + "\n\n\n" + "Use the number keys or function keys F1-F10 " + "(use F10 for 0).\n"); + { + int which2; + char k[200]; + sprintf (k, "Recovery key ID (to identify your key): " + "%08X-%04X-%04X-%04X%08X\n\n", + random() & 0xFFFFFFFF, + random() & 0xFFFF, + random() & 0xFFFF, + random() & 0xFFFF, + random() & 0xFFFFFFFF); + BSOD_TEXT (bst, LEFT, k); + + which2 = random() % 4; + switch (which2) { + case 0: + BSOD_TEXT (bst, LEFT, + "Bitlocker needs your recovery key to unlock your " + "drive because Secure Boot policy has unexpectedly " + "changed." + "\n\n"); + break; + case 1: + BSOD_TEXT (bst, LEFT, + "Bitlocker needs your recovery key to unlock your " + "PC's configuration has changed. This may have happened " + "because a disc or USB device ws inserted. Removing it " + "and restarting your PC may fix this problem." + "\n\n"); + break; + case 3: + BSOD_TEXT (bst, LEFT, + "Bitlocker needs your recovery key to unlock your drive " + "because Secure Boot has been disabled. Either Secure " + "Boot must be re-enabled, or BitLocker must be suspended " + "for Windows to start normally." + "\n\n"); + break; + default: + break; + } + } + + BSOD_TEXT (bst, LEFT, + "Here's how to find your key:\n" + "- Sign in on another device and go to: " + "https://www.jwz.org/\n" + "- For more information go to: " + "https://www.jwz.org/xscreensaver/"); + break; + + case 4: + BSOD_TEXT (bst, LEFT, "Recovery\n\n"); + BSOD_FONT (bst, 0); + BSOD_TEXT (bst, LEFT, + "There are no more BitLocker recovery options on your PC" + "\n\n"); + BSOD_FONT (bst, 2); + BSOD_TEXT (bst, LEFT, + "You'll need to use the recovery tools on your installation " + "media. If you don't have any installation media (like a " + "disc or USB device), contact your system administrator or " + "PC manufacturer."); + bottom = ("Press Enter to try again\n" + "Press F8 for Startup Settings\n" + "Press Esc for UEFI Firmware Settings"); + break; + + default: + abort(); + } + + BSOD_FONT (bst, 0); + BSOD_MOVETO (bst, 0, bst->xgwa.height - top - + (bst->fontB->ascent + bst->fontB->descent) * 1); + BSOD_TEXT (bst, LEFT, bottom); + + XClearWindow (dpy, window); + return bst; +} + + /* As seen in Portal 2. By jwz. */ static struct bsod_state * @@ -6734,6 +7027,33 @@ gnome (Display *dpy, Window window) } +/* Linux kernel panic obscured by systemd, 2024. + https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/drm_panic.c + */ +static struct bsod_state * +systemd (Display *dpy, Window window) +{ + struct bsod_state *bst = make_bsod_state (dpy, window, "systemd", "Systemd"); + int lh = (bst->font->ascent + bst->font->descent); + BSOD_MOVETO (bst, 0, lh); + BSOD_TEXT (bst, LEFT, + " .--. _\n" + " |o_o | | |\n" + " |:_/ | | |\n" + " // \\ \\ |_|\n" + " (| | ) _\n" + " /'\\_ _/`\\ (_)\n" + " \\___)=(___/\n"); + BSOD_MOVETO (bst, 0, (bst->xgwa.height / 2) - lh); + BSOD_TEXT (bst, CENTER, + "KERNEL PANIC !\n" + "\n" + "Please reboot your computer."); + XClearWindow (dpy, window); + return bst; +} + + /***************************************************************************** *****************************************************************************/ @@ -6746,6 +7066,7 @@ static const struct { { "NT", windows_nt }, { "Win2K", windows_other }, { "Win10", windows_10 }, + { "Bitlocker", bitlocker }, { "Ransomware", windows_ransomware }, { "Amiga", amiga }, { "Mac", mac }, @@ -6781,6 +7102,7 @@ static const struct { { "Tivo", tivo }, { "Nintendo", nintendo }, { "Gnome", gnome }, + { "Systemd", systemd }, }; @@ -7076,6 +7398,7 @@ static const char *bsod_defaults [] = { "*doNT: True", "*doWin2K: True", "*doWin10: True", + "*doBitlocker: True", "*doRansomware: True", "*doAmiga: True", "*doMac: True", @@ -7109,6 +7432,7 @@ static const char *bsod_defaults [] = { "*doTivo: True", "*doNintendo: True", "*doGnome: True", + "*doSystemd: True", ".foreground: White", ".background: Black", @@ -7130,6 +7454,12 @@ static const char *bsod_defaults [] = { ".win10.foreground: White", ".win10.background: #1070AA", + ".win10r.foreground: White", + ".win10r.background: #1070AA", + + ".bitlocker.foreground: White", + ".bitlocker.background: #1070AA", + ".ransomware.foreground: White", ".ransomware.background: #841212", ".ransomware.foreground2: Black", /* ransom note */ @@ -7246,6 +7576,9 @@ static const char *bsod_defaults [] = { ".gnome.background2: #F0F0F0", ".gnome.foreground2: #2E3436", + ".systemd.background: #0000AA", + ".systemd.foreground: White", + "*dontClearRoot: True", ANALOGTV_DEFAULTS @@ -7272,9 +7605,19 @@ static const char *bsod_defaults [] = { ".win10.font: Arial 24, Helvetica 24", ".win10.bigFont: Arial 24, Helvetica 24", - ".win10.fontB: Arial 36, Helvetica 36", + ".win10.fontB: Arial 90, Helvetica 36", ".win10.fontC: Arial 16, Helvetica 16", + ".win10r.font: Arial 16, Helvetica 24", + ".win10r.bigFont: Arial 16, Helvetica 24", + ".win10r.fontB: Arial 28, Helvetica 36", + ".win10r.fontC: Arial 50, Helvetica 16", + + ".bitlocker.font: Arial 24, Helvetica 24", + ".bitlocker.bigFont: Arial 24, Helvetica 24", + ".bitlocker.fontB: Arial 36, Helvetica 36", + ".bitlocker.fontC: Arial 18, Helvetica 18", + /* "Arial" loads "ArialMT" but "Arial Bold" does not load "Arial-BoldMT"? */ ".ransomware.font: Arial 12, Helvetica 12", ".ransomware.bigFont: Arial 12, Helvetica 12", @@ -7313,6 +7656,9 @@ static const char *bsod_defaults [] = { ".gnome.font: Helvetica Bold 13", ".gnome.bigFont: Helvetica Bold 13", ".gnome.fontB: Helvetica 13", + + ".systemd.font: Classic Console 14", + ".systemd.bigFont: Classic Console 14", 0 }; @@ -7328,6 +7674,8 @@ static const XrmOptionDescRec bsod_options [] = { { "-no-2k", ".doWin2K", XrmoptionNoArg, "False" }, { "-win10", ".doWin10", XrmoptionNoArg, "True" }, { "-no-win10", ".doWin10", XrmoptionNoArg, "False" }, + { "-bitlocker", ".doBitlocker", XrmoptionNoArg, "True" }, + { "-no-bitlocker", ".doBitlocker", XrmoptionNoArg, "False" }, { "-ransomware", ".doRansomware", XrmoptionNoArg, "True" }, { "-no-ransomware", ".doRansomware", XrmoptionNoArg, "False" }, { "-amiga", ".doAmiga", XrmoptionNoArg, "True" }, @@ -7394,6 +7742,8 @@ static const XrmOptionDescRec bsod_options [] = { { "-no-nintendo", ".doNintendo", XrmoptionNoArg, "False" }, { "-gnome", ".doGnome", XrmoptionNoArg, "True" }, { "-no-gnome", ".doGnome", XrmoptionNoArg, "False" }, + { "-systemd", ".doSystemd", XrmoptionNoArg, "True" }, + { "-no-systemd", ".doSystemd", XrmoptionNoArg, "False" }, ANALOGTV_OPTIONS { 0, 0, 0, 0 } }; diff --git a/hacks/check-configs.pl b/hacks/check-configs.pl index bbcc15f9..58d72170 100755 --- a/hacks/check-configs.pl +++ b/hacks/check-configs.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright © 2008-2024 Jamie Zawinski +# Copyright © 2008-2025 Jamie Zawinski # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that @@ -21,7 +21,7 @@ use diagnostics; use strict; my $progname = $0; $progname =~ s@.*/@@g; -my ($version) = ('$Revision: 1.44 $' =~ m/\s(\d[.\d]+)\s/s); +my ($version) = ('$Revision: 1.49 $' =~ m/\s(\d[.\d]+)\s/s); my $verbose = 0; my $debug_p = 0; @@ -671,21 +671,25 @@ sub munge_blurb($$$$) { } } + my $desc0 = "$desc"; + utf8::decode($desc0); # Pack UTF-8 into wide chars. + my $desc1 = ("$name, version $vers.\n\n" . # savername.xml $desc . "\n" . "\n" . "From the XScreenSaver collection: " . "https://www.jwz.org/xscreensaver/\n" . - "Copyright \302\251 $year by $authors.\n"); + "Copyright \x{A9} $year by $authors.\n"); my $desc2 = ("$name $vers,\n" . # Info.plist - "\302\251 $year $authors.\n" . + "\x{A9} $year $authors.\n" . #"From the XScreenSaver collection:\n" . #"https://www.jwz.org/xscreensaver/\n" . "\n" . $desc . "\n"); - utf8::decode($desc1); # Pack UTF-8 into wide chars. + + utf8::decode($desc1); # Pack UTF-8 into wide chars (redundant?) utf8::decode($desc2); # unwrap lines, but only when it's obviously ok: leave blank lines, @@ -752,6 +756,16 @@ sub build_android(@) { $saver_class =~ s/\]\[/2/gs; $saver_class =~ s/[-_\s]//gs; + # If the saver's title is not case-insensitively the same as its progname + # after removing spaces, the class name has to be the progname, or + # jwxyz_nativeInit is not able to find it in the function_table. + # (Cuboctahedron Eversion, Möbius, MöbiusGears, Moiré, Moiré2.) + # + if (lc($saver_class) ne lc($saver)) { + $saver_class = $saver; + $saver_class =~ s/^(.)/\U$1/s; + } + my $settings = ''; my $localize0 = sub($$) { @@ -1137,6 +1151,8 @@ sub build_android(@) { "android.permission.INTERNET\" />\n" . " \n" . + " \n" . " = 0) { $_ = shift @ARGV; if (m/^--?verbose$/) { $verbose++; } + elsif (m/^--?force$/) { $force_p++; } elsif (m/^-v+$/) { $verbose += length($_)-1; } elsif (m/^--?debug$/s) { $debug_p++; } elsif (m/^--?build-android$/s) { $android_p++; } @@ -1261,7 +1279,7 @@ sub main() { # else { usage; } } - usage unless ($#files >= 0); + usage unless ($#files >= 0 || $force_p); my $failures = 0; foreach my $file (@files) { $failures += check_config ($file, $android_p); diff --git a/hacks/config/README b/hacks/config/README index 6b2c000f..3e68861c 100644 --- a/hacks/config/README +++ b/hacks/config/README @@ -4,8 +4,8 @@ a screen saver and locker for the X window system by Jamie Zawinski - version 6.09 - 07-Jun-2024 + version 6.10 + 27-Apr-2025 https://www.jwz.org/xscreensaver/ diff --git a/hacks/config/bsod.xml b/hacks/config/bsod.xml index 3938147b..090e9182 100644 --- a/hacks/config/bsod.xml +++ b/hacks/config/bsod.xml @@ -18,13 +18,14 @@ - + + @@ -67,6 +68,7 @@ + diff --git a/hacks/config/dumpsterfire.xml b/hacks/config/dumpsterfire.xml new file mode 100644 index 00000000..193fe07f --- /dev/null +++ b/hacks/config/dumpsterfire.xml @@ -0,0 +1,39 @@ + + + + + + + diff --git a/hacks/config/hopffibration.xml b/hacks/config/hopffibration.xml new file mode 100644 index 00000000..37d862de --- /dev/null +++ b/hacks/config/hopffibration.xml @@ -0,0 +1,82 @@ + + + + + diff --git a/hacks/config/klondike.xml b/hacks/config/klondike.xml new file mode 100644 index 00000000..e74d2219 --- /dev/null +++ b/hacks/config/klondike.xml @@ -0,0 +1,50 @@ + + + + + + + diff --git a/hacks/config/platonicfolding.xml b/hacks/config/platonicfolding.xml new file mode 100644 index 00000000..5b59c491 --- /dev/null +++ b/hacks/config/platonicfolding.xml @@ -0,0 +1,74 @@ + + + + + diff --git a/hacks/config/sonar.xml b/hacks/config/sonar.xml index 74061061..db74a4f1 100644 --- a/hacks/config/sonar.xml +++ b/hacks/config/sonar.xml @@ -23,8 +23,9 @@