From 49f5b54f312fe4ac2e9bc47581a72451bd0e8439 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Mon, 2 Mar 2009 00:43:38 -0500 Subject: [PATCH] http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscreensaver-5.00.tar.bz2 -rw-r--r-- 1 zblaxell zblaxell 4002481 May 23 2006 xscreensaver-5.00.tar.bz2 e04c97218d3af6b98d4d45579811cfca4c276580 xscreensaver-5.00.tar.bz2 --- Makefile.in | 70 +- OSX/._XScreenSaver.icns | Bin 0 -> 39555 bytes OSX/._bindist-DS_Store | Bin 0 -> 82 bytes OSX/AppController.h | 21 + OSX/AppController.m | 200 + OSX/English.lproj/InfoPlist.strings | Bin 0 -> 92 bytes OSX/English.lproj/MainMenu.nib/classes.nib | 9 + OSX/English.lproj/MainMenu.nib/info.nib | 21 + .../MainMenu.nib/keyedobjects.nib | Bin 0 -> 11645 bytes OSX/InvertedSlider.h | 20 + OSX/InvertedSlider.m | 102 + OSX/Makefile | 92 + OSX/PrefsReader.h | 39 + OSX/PrefsReader.m | 283 + OSX/README | 10 + OSX/SaverTester.plist | 30 + OSX/XScreenSaver.icns | Bin 0 -> 39163 bytes OSX/XScreenSaver.plist | 30 + OSX/XScreenSaverConfigSheet.h | 38 + OSX/XScreenSaverConfigSheet.m | 1748 + OSX/XScreenSaverDMG.icns | Bin 0 -> 35120 bytes OSX/XScreenSaverGLView.h | 26 + OSX/XScreenSaverGLView.m | 251 + OSX/XScreenSaverSubclass.m | 33 + OSX/XScreenSaverView.h | 42 + OSX/XScreenSaverView.m | 618 + OSX/bindist-DS_Store | Bin 0 -> 12292 bytes OSX/bindist.rtf | 49 + OSX/jwxyz-timers.h | 29 + OSX/jwxyz-timers.m | 383 + OSX/jwxyz.h | 700 + OSX/jwxyz.m | 2697 ++ OSX/main.m | 17 + OSX/osxgrabscreen.m | 228 + OSX/update-info-plist.pl | 272 + OSX/xscreensaver_Prefix.pch | 15 + README | 107 +- README.debugging | 162 - README.hacking | 163 + config.guess | 284 +- config.h.in | 8 - config.sub | 100 +- configure | 201 +- configure.in | 93 +- driver/Makefile.in | 62 +- driver/XScreenSaver.ad.in | 90 +- driver/XScreenSaver_ad.h | 86 +- driver/demo-Gtk-conf.c | 106 +- driver/demo-Gtk.c | 97 +- driver/exec.c | 3 +- driver/exec.h | 21 + driver/lock.c | 249 +- driver/passwd-pam.c | 2 + driver/passwd-pwent.c | 5 + driver/passwd.c | 3 + driver/prefs.c | 198 +- driver/prefs.h | 20 +- driver/remote.c | 2 +- driver/splash.c | 87 +- driver/stderr.c | 12 +- driver/subprocs.c | 9 +- driver/test-passwd.c | 20 +- driver/test-uid.c | 2 +- driver/windows.c | 16 +- driver/xscreensaver-command.c | 2 +- driver/xscreensaver-getimage-file | 445 +- driver/xscreensaver-getimage.c | 10 +- driver/xscreensaver-text | 129 +- driver/xscreensaver.c | 49 +- driver/xscreensaver.h | 6 +- driver/xscreensaver.pam | 5 +- hacks/Makefile.in | 294 +- hacks/analogtv.c | 185 +- hacks/analogtv.h | 23 +- hacks/anemone.c | 431 +- hacks/anemotaxis.c | 498 +- hacks/ant.c | 71 +- hacks/apollonian.c | 64 +- hacks/apple2-main.c | 286 +- hacks/apple2.c | 160 +- hacks/apple2.h | 29 +- hacks/attraction.c | 830 +- hacks/automata.h | 3 + hacks/barcode.c | 575 +- hacks/blaster.c | 1235 +- hacks/blitspin.c | 375 +- hacks/bouboule.c | 26 +- hacks/boxfit.c | 269 +- hacks/braid.c | 54 +- hacks/bsod.c | 4518 +- hacks/bubbles-default.c | 2 - hacks/bubbles.c | 720 +- hacks/bubbles.h | 13 +- hacks/bumps.c | 219 +- hacks/bumps.h | 23 +- hacks/ccurve.c | 376 +- hacks/celtic.c | 495 +- hacks/celtic.man | 2 +- hacks/change_locale.h | 17 + hacks/cloudlife.c | 284 +- hacks/compass.c | 448 +- hacks/compile_axp.com | 2 - hacks/compile_decc.com | 2 - hacks/config/README | 46 +- hacks/config/anemone.xml | 4 +- hacks/config/anemotaxis.xml | 4 +- hacks/config/ant.xml | 6 +- hacks/config/antinspect.xml | 3 +- hacks/config/antmaze.xml | 5 +- hacks/config/antspotlight.xml | 8 +- hacks/config/apollonian.xml | 4 +- hacks/config/apple2.xml | 29 +- hacks/config/atlantis.xml | 21 +- hacks/config/attraction.xml | 17 +- hacks/config/atunnel.xml | 14 +- hacks/config/barcode.xml | 11 +- hacks/config/blaster.xml | 3 +- hacks/config/blinkbox.xml | 3 +- hacks/config/blitspin.xml | 25 +- hacks/config/blocktube.xml | 14 +- hacks/config/boing.xml | 4 +- hacks/config/bouboule.xml | 7 +- hacks/config/bouncingcow.xml | 11 +- hacks/config/boxed.xml | 3 +- hacks/config/boxfit.xml | 12 +- hacks/config/braid.xml | 5 +- hacks/config/bsod.xml | 10 +- hacks/config/bubble3d.xml | 7 +- hacks/config/bubbles.xml | 15 +- hacks/config/bumps.xml | 10 +- hacks/config/cage.xml | 14 +- hacks/config/carousel.xml | 21 +- hacks/config/ccurve.xml | 13 +- hacks/config/celtic.xml | 3 +- hacks/config/circuit.xml | 4 +- hacks/config/cloudlife.xml | 5 +- hacks/config/compass.xml | 6 +- hacks/config/coral.xml | 8 +- hacks/config/cosmos.xml | 4 +- hacks/config/crackberg.xml | 45 +- hacks/config/critical.xml | 8 +- hacks/config/crystal.xml | 4 +- hacks/config/cube21.xml | 26 +- hacks/config/cubenetic.xml | 19 +- hacks/config/cubestorm.xml | 4 +- hacks/config/cynosure.xml | 7 +- hacks/config/dangerball.xml | 3 +- hacks/config/decayscreen.xml | 5 +- hacks/config/deco.xml | 11 +- hacks/config/deluxe.xml | 11 +- hacks/config/demon.xml | 4 +- hacks/config/discrete.xml | 6 +- hacks/config/distort.xml | 12 +- hacks/config/dnalogo.xml | 21 + hacks/config/drift.xml | 12 +- hacks/config/electricsheep.xml | 13 +- hacks/config/endgame.xml | 4 +- hacks/config/engine.xml | 3 +- hacks/config/epicycle.xml | 5 +- hacks/config/eruption.xml | 6 +- hacks/config/euler2d.xml | 3 +- hacks/config/extrusion.xml | 13 +- hacks/config/fadeplot.xml | 3 +- hacks/config/fiberlamp.xml | 4 +- hacks/config/fireflies.xml | 4 +- hacks/config/fireworkx.xml | 14 +- hacks/config/flag.xml | 6 +- hacks/config/flame.xml | 4 +- hacks/config/flipflop.xml | 11 +- hacks/config/flipscreen3d.xml | 6 +- hacks/config/fliptext.xml | 18 +- hacks/config/flow.xml | 16 +- hacks/config/fluidballs.xml | 5 +- hacks/config/flurry.xml | 24 +- hacks/config/flyingtoasters.xml | 11 +- hacks/config/fontglide.xml | 18 +- hacks/config/forest.xml | 5 +- hacks/config/fuzzyflakes.xml | 5 +- hacks/config/galaxy.xml | 10 +- hacks/config/gears.xml | 16 +- hacks/config/gflux.xml | 9 +- hacks/config/glblur.xml | 13 +- hacks/config/gleidescope.xml | 19 +- hacks/config/glforestfire.xml | 25 +- hacks/config/glhanoi.xml | 15 +- hacks/config/glknots.xml | 11 +- hacks/config/glmatrix.xml | 16 +- hacks/config/glplanet.xml | 10 +- hacks/config/glschool.xml | 32 + hacks/config/glslideshow.xml | 17 +- hacks/config/glsnake.xml | 9 +- hacks/config/gltext.xml | 23 +- hacks/config/goban.xml | 4 +- hacks/config/goop.xml | 11 +- hacks/config/grav.xml | 9 +- hacks/config/greynetic.xml | 5 +- hacks/config/halftone.xml | 8 +- hacks/config/halo.xml | 9 +- hacks/config/helix.xml | 5 +- hacks/config/hopalong.xml | 5 +- hacks/config/hyperball.xml | 7 +- hacks/config/hypercube.xml | 6 +- hacks/config/hypertorus.xml | 99 +- hacks/config/ifs.xml | 33 +- hacks/config/imsmap.xml | 25 +- hacks/config/interaggregate.xml | 19 +- hacks/config/interference.xml | 8 +- hacks/config/intermomentary.xml | 24 +- hacks/config/jigglypuff.xml | 110 +- hacks/config/jigsaw.xml | 5 +- hacks/config/juggle.xml | 29 +- hacks/config/juggler3d.xml | 7 +- hacks/config/julia.xml | 17 +- hacks/config/kaleidescope.xml | 18 +- hacks/config/klein.xml | 6 +- hacks/config/kumppa.xml | 11 +- hacks/config/lament.xml | 15 +- hacks/config/laser.xml | 4 +- hacks/config/lavalite.xml | 36 +- hacks/config/lightning.xml | 6 +- hacks/config/lisa.xml | 6 +- hacks/config/lissie.xml | 5 +- hacks/config/lmorph.xml | 4 +- hacks/config/loop.xml | 5 +- hacks/config/maze.xml | 8 +- hacks/config/memscroller.xml | 4 +- hacks/config/menger.xml | 18 +- hacks/config/metaballs.xml | 3 +- hacks/config/mirrorblob.xml | 31 +- hacks/config/mismunch.xml | 4 +- hacks/config/moebius.xml | 23 +- hacks/config/moire.xml | 14 +- hacks/config/moire2.xml | 10 +- hacks/config/molecule.xml | 22 +- hacks/config/morph3d.xml | 16 +- hacks/config/mountain.xml | 10 +- hacks/config/munch.xml | 6 +- hacks/config/nerverot.xml | 5 +- hacks/config/noof.xml | 3 +- hacks/config/noseguy.xml | 19 +- hacks/config/pacman.xml | 3 +- hacks/config/pedal.xml | 7 +- hacks/config/penetrate.xml | 5 +- hacks/config/penrose.xml | 17 +- hacks/config/petri.xml | 7 +- hacks/config/phosphor.xml | 18 +- hacks/config/piecewise.xml | 11 +- hacks/config/pinion.xml | 3 +- hacks/config/pipes.xml | 39 +- hacks/config/polyhedra.xml | 17 +- hacks/config/polyominoes.xml | 4 +- hacks/config/polytopes.xml | 95 +- hacks/config/pong.xml | 9 +- hacks/config/popsquares.xml | 4 +- hacks/config/providence.xml | 9 +- hacks/config/pulsar.xml | 24 +- hacks/config/pyro.xml | 5 +- hacks/config/qix.xml | 11 +- hacks/config/queens.xml | 3 +- hacks/config/rd-bomb.xml | 11 +- hacks/config/rdbomb.xml | 55 + hacks/config/ripples.xml | 8 +- hacks/config/rocks.xml | 9 +- hacks/config/rorschach.xml | 12 +- hacks/config/rotor.xml | 5 +- hacks/config/rotzoomer.xml | 15 +- hacks/config/rubik.xml | 6 +- hacks/config/sballs.xml | 14 +- hacks/config/shadebobs.xml | 9 +- hacks/config/sierpinski.xml | 4 +- hacks/config/sierpinski3d.xml | 10 +- hacks/config/slidescreen.xml | 22 +- hacks/config/slip.xml | 8 +- hacks/config/sonar.xml | 16 +- hacks/config/speedmine.xml | 28 +- hacks/config/sphere.xml | 6 +- hacks/config/sphereeversion.xml | 7 +- hacks/config/spheremonics.xml | 18 +- hacks/config/spiral.xml | 5 +- hacks/config/spotlight.xml | 11 +- hacks/config/sproingies.xml | 22 +- hacks/config/squiral.xml | 5 +- hacks/config/ssystem.xml | 26 - hacks/config/stairs.xml | 10 +- hacks/config/starfish.xml | 13 +- hacks/config/starwars.xml | 32 +- hacks/config/stonerview.xml | 11 +- hacks/config/strange.xml | 3 +- hacks/config/substrate.xml | 7 +- hacks/config/superquadrics.xml | 20 +- hacks/config/swirl.xml | 8 +- hacks/config/t3d.xml | 7 +- hacks/config/tangram.xml | 13 +- hacks/config/thornbird.xml | 11 +- hacks/config/timetunnel.xml | 6 +- hacks/config/topblock.xml | 51 + hacks/config/triangle.xml | 4 +- hacks/config/truchet.xml | 5 +- hacks/config/twang.xml | 14 +- hacks/config/vermiculate.xml | 4 +- hacks/config/vidwhacker.xml | 14 +- hacks/config/vines.xml | 7 +- hacks/config/wander.xml | 5 +- hacks/config/webcollage.xml | 4 +- hacks/config/whirlwindwarp.xml | 5 +- hacks/config/whirlygig.xml | 8 +- hacks/config/worm.xml | 6 +- hacks/config/wormhole.xml | 5 +- hacks/config/xanalogtv.xml | 3 +- hacks/config/xaos.xml | 8 +- hacks/config/xdaliclock.xml | 14 +- hacks/config/xearth.xml | 93 - hacks/config/xfishtank.xml | 33 - hacks/config/xflame.xml | 7 +- hacks/config/xjack.xml | 5 +- hacks/config/xlyap.xml | 6 +- hacks/config/xmatrix.xml | 21 +- hacks/config/xmountains.xml | 12 +- hacks/config/xplanet.xml | 6 +- hacks/config/xrayswarm.xml | 6 +- hacks/config/xsnow.xml | 6 +- hacks/config/xspirograph.xml | 5 +- hacks/config/xteevee.xml | 6 +- hacks/config/zoom.xml | 8 +- hacks/coral.c | 355 +- hacks/critical.c | 390 +- hacks/crystal.c | 35 +- hacks/cynosure.c | 374 +- hacks/decayscreen.c | 317 +- hacks/deco.c | 205 +- hacks/deluxe.c | 368 +- hacks/demon.c | 63 +- hacks/discrete.c | 70 +- hacks/distort.c | 740 +- hacks/drift.c | 60 +- hacks/epicycle.c | 529 +- hacks/eruption.c | 499 +- hacks/euler2d.c | 46 +- hacks/fadeplot.c | 47 +- hacks/fiberlamp.c | 135 +- hacks/fireworkx.c | 413 +- hacks/flag.c | 84 +- hacks/flame.c | 239 +- hacks/flow.c | 46 +- hacks/flow.man | 2 +- hacks/fluidballs.c | 255 +- hacks/fontglide.c | 446 +- hacks/forest.c | 61 +- hacks/fuzzyflakes.c | 417 +- hacks/galaxy.c | 255 +- hacks/glx/Makefile.in | 140 +- hacks/glx/antinspect.c | 137 +- hacks/glx/antmaze.c | 672 +- hacks/glx/ants.h | 32 +- hacks/glx/antspotlight.c | 304 +- hacks/glx/atlantis.c | 60 +- hacks/glx/atlantis.h | 16 +- hacks/glx/atunnel.c | 96 +- hacks/glx/b_draw.c | 12 +- hacks/glx/b_lockglue.c | 52 +- hacks/glx/b_sphere.c | 135 +- hacks/glx/blinkbox.c | 472 +- hacks/glx/blocktube.c | 212 +- hacks/glx/boing.c | 71 +- hacks/glx/bouncingcow.c | 50 +- hacks/glx/boxed.c | 69 +- hacks/glx/bubble3d.c | 10 +- hacks/glx/bubble3d.h | 25 +- hacks/glx/buildlwo.c | 12 +- hacks/glx/buildlwo.h | 20 +- hacks/glx/cage.c | 64 +- hacks/glx/carousel.c | 541 +- hacks/glx/chessmodels.c | 2649 +- hacks/glx/chessmodels.h | 12 +- hacks/glx/circuit.c | 885 +- hacks/glx/cow_face.c | 6 +- hacks/glx/cow_hide.c | 6 +- hacks/glx/cow_hoofs.c | 6 +- hacks/glx/cow_horns.c | 6 +- hacks/glx/cow_tail.c | 6 +- hacks/glx/cow_udder.c | 6 +- hacks/glx/crackberg.c | 405 +- hacks/glx/cube21.c | 383 +- hacks/glx/cubenetic.c | 54 +- hacks/glx/cubestorm.c | 46 +- hacks/glx/dangerball.c | 61 +- hacks/glx/dnalogo.c | 1270 + hacks/glx/dolphin.c | 694 +- hacks/glx/dxf2gl.pl | 8 +- hacks/glx/endgame.c | 534 +- hacks/glx/endgame.man | 3 + hacks/glx/engine.c | 386 +- hacks/glx/extrusion-helix2.c | 13 +- hacks/glx/extrusion-helix3.c | 13 +- hacks/glx/extrusion-helix4.c | 13 +- hacks/glx/extrusion-joinoffset.c | 13 +- hacks/glx/extrusion-screw.c | 19 +- hacks/glx/extrusion-taper.c | 12 +- hacks/glx/extrusion-twistoid.c | 12 +- hacks/glx/extrusion.c | 190 +- hacks/glx/extrusion.h | 53 + hacks/glx/flipflop.c | 92 +- hacks/glx/flipscreen3d.c | 415 +- hacks/glx/fliptext.c | 114 +- hacks/glx/flurry.c | 34 +- hacks/glx/flyingtoasters.c | 64 +- hacks/glx/font-ximage.c | 19 +- hacks/glx/fps.c | 205 +- hacks/glx/gears.c | 82 +- hacks/glx/gflux.c | 452 +- hacks/glx/glblur.c | 48 +- hacks/glx/gleidescope.c | 204 +- hacks/glx/glforestfire.c | 167 +- hacks/glx/glhanoi.c | 348 +- hacks/glx/glhanoi.man | 8 +- hacks/glx/glknots.c | 67 +- hacks/glx/gllist.c | 5 +- hacks/glx/gllist.h | 12 +- hacks/glx/glmatrix.c | 119 +- hacks/glx/glplanet.c | 38 +- hacks/glx/glschool.c | 195 + hacks/glx/glschool.h | 17 + hacks/glx/glschool.man | 126 + hacks/glx/glschool_alg.c | 364 + hacks/glx/glschool_alg.h | 126 + hacks/glx/glschool_gl.c | 276 + hacks/glx/glschool_gl.h | 37 + hacks/glx/glslideshow.c | 153 +- hacks/glx/glsnake.c | 486 +- hacks/glx/gltext.c | 72 +- hacks/glx/gltrackball.c | 15 +- hacks/glx/glut_stroke.c | 10 +- hacks/glx/glut_swidth.c | 10 +- hacks/glx/glxfonts.c | 50 +- hacks/glx/grab-ximage.c | 147 +- hacks/glx/grab-ximage.h | 44 +- hacks/glx/hypertorus.c | 187 +- hacks/glx/jigglypuff.c | 100 +- hacks/glx/juggler3d.c | 83 +- hacks/glx/juggler3d.man | 2 +- hacks/glx/klein.c | 42 +- hacks/glx/lament.c | 155 +- hacks/glx/lavalite.c | 103 +- hacks/glx/marching.c | 13 +- hacks/glx/menger.c | 102 +- hacks/glx/mirrorblob.c | 743 +- hacks/glx/moebius.c | 135 +- hacks/glx/molecule.c | 219 +- hacks/glx/molecules.sh | 17 + hacks/glx/morph3d.c | 99 +- hacks/glx/noof.c | 323 +- hacks/glx/normals.c | 6 +- hacks/glx/normals.h | 6 + hacks/glx/pinion.c | 126 +- hacks/glx/pipeobjs.c | 58 +- hacks/glx/pipes.c | 112 +- hacks/glx/polyhedra-gl.c | 79 +- hacks/glx/polyhedra.c | 19 +- hacks/glx/polytopes.c | 530 +- hacks/glx/providence.c | 395 +- hacks/glx/pulsar.c | 179 +- hacks/glx/queens.c | 283 +- hacks/glx/rotator.c | 8 +- hacks/glx/rubik.c | 103 +- hacks/glx/s1_1.c | 6 +- hacks/glx/s1_2.c | 6 +- hacks/glx/s1_3.c | 6 +- hacks/glx/s1_4.c | 6 +- hacks/glx/s1_5.c | 6 +- hacks/glx/s1_6.c | 6 +- hacks/glx/s1_b.c | 6 +- hacks/glx/sballs.c | 156 +- hacks/glx/shark.c | 416 +- hacks/glx/sierpinski3d.c | 105 +- hacks/glx/sphere.c | 25 +- hacks/glx/sphere.h | 2 +- hacks/glx/spheremonics.c | 82 +- hacks/glx/sproingies.c | 45 +- hacks/glx/sproingies.h | 25 + hacks/glx/sproingiewrap.c | 60 +- hacks/glx/stairs.c | 119 +- hacks/glx/starwars.c | 123 +- hacks/glx/stonerview-move.c | 142 +- hacks/glx/stonerview-move.h | 16 +- hacks/glx/stonerview-osc.c | 108 +- hacks/glx/stonerview-osc.h | 29 +- hacks/glx/stonerview-view.c | 448 +- hacks/glx/stonerview.c | 163 +- hacks/glx/stonerview.h | 60 + hacks/glx/superquadrics.c | 100 +- hacks/glx/swim.c | 5 +- hacks/glx/tangram.c | 120 +- hacks/glx/tangram_shapes.c | 10 +- hacks/glx/texfont.c | 104 +- hacks/glx/timetunnel.c | 161 +- hacks/glx/toast.c | 6 +- hacks/glx/toast2.c | 6 +- hacks/glx/toaster.c | 6 +- hacks/glx/toaster_base.c | 6 +- hacks/glx/toaster_handle.c | 6 +- hacks/glx/toaster_handle2.c | 6 +- hacks/glx/toaster_jet.c | 6 +- hacks/glx/toaster_knob.c | 6 +- hacks/glx/toaster_slots.c | 6 +- hacks/glx/toaster_wing.c | 6 +- hacks/glx/topblock.c | 835 + hacks/glx/topblock.h | 45 + hacks/glx/topblock.man | 172 + hacks/glx/trackball.c | 27 +- hacks/glx/tube.c | 52 +- hacks/glx/tube.h | 4 +- hacks/glx/tunnel_draw.c | 165 +- hacks/glx/tunnel_draw.h | 13 +- hacks/glx/whale.c | 621 +- hacks/glx/{xlock-gl.c => xlock-gl-utils.c} | 51 +- hacks/glx/xpm-ximage.c | 145 +- hacks/glx/xpm-ximage.h | 3 +- hacks/glx/xscreensaver-gl-helper.c | 1 - hacks/goop.c | 150 +- hacks/grav.c | 37 +- hacks/greynetic.c | 185 +- hacks/halftone.c | 167 +- hacks/halo.c | 438 +- hacks/halo.man | 11 +- hacks/helix.c | 394 +- hacks/hopalong.c | 51 +- hacks/hyperball.c | 858 +- hacks/hypercube.c | 220 +- hacks/ifs.c | 680 +- hacks/ifs.man | 42 +- hacks/images/6x10font.xbm | 190 + hacks/images/apple2font.xbm | 41 + hacks/images/atari.xbm | 10 +- hacks/images/bubbles/blood1.xpm | 137 +- hacks/images/bubbles/blood10.xpm | 404 +- hacks/images/bubbles/blood11.xpm | 427 +- hacks/images/bubbles/blood2.xpm | 189 +- hacks/images/bubbles/blood3.xpm | 222 +- hacks/images/bubbles/blood4.xpm | 275 +- hacks/images/bubbles/blood5.xpm | 310 +- hacks/images/bubbles/blood6.xpm | 336 +- hacks/images/bubbles/blood7.xpm | 351 +- hacks/images/bubbles/blood8.xpm | 372 +- hacks/images/bubbles/blood9.xpm | 384 +- hacks/images/bubbles/blue1.xpm | 115 +- hacks/images/bubbles/blue10.xpm | 385 +- hacks/images/bubbles/blue11.xpm | 411 +- hacks/images/bubbles/blue2.xpm | 167 +- hacks/images/bubbles/blue3.xpm | 195 +- hacks/images/bubbles/blue4.xpm | 261 +- hacks/images/bubbles/blue5.xpm | 280 +- hacks/images/bubbles/blue6.xpm | 311 +- hacks/images/bubbles/blue7.xpm | 332 +- hacks/images/bubbles/blue8.xpm | 349 +- hacks/images/bubbles/blue9.xpm | 364 +- hacks/images/bubbles/glass1.xpm | 145 +- hacks/images/bubbles/glass10.xpm | 399 +- hacks/images/bubbles/glass11.xpm | 423 +- hacks/images/bubbles/glass2.xpm | 177 +- hacks/images/bubbles/glass3.xpm | 211 +- hacks/images/bubbles/glass4.xpm | 284 +- hacks/images/bubbles/glass5.xpm | 303 +- hacks/images/bubbles/glass6.xpm | 334 +- hacks/images/bubbles/glass7.xpm | 351 +- hacks/images/bubbles/glass8.xpm | 368 +- hacks/images/bubbles/glass9.xpm | 380 +- hacks/images/bubbles/jade1.xpm | 139 +- hacks/images/bubbles/jade10.xpm | 405 +- hacks/images/bubbles/jade11.xpm | 430 +- hacks/images/bubbles/jade2.xpm | 179 +- hacks/images/bubbles/jade3.xpm | 215 +- hacks/images/bubbles/jade4.xpm | 274 +- hacks/images/bubbles/jade5.xpm | 311 +- hacks/images/bubbles/jade6.xpm | 338 +- hacks/images/bubbles/jade7.xpm | 353 +- hacks/images/bubbles/jade8.xpm | 371 +- hacks/images/bubbles/jade9.xpm | 385 +- hacks/images/jigsaw/jigsaw.xbm | 1614 - hacks/images/jigsaw/jigsaw_a_e_f.xbm | 77 - hacks/images/jigsaw/jigsaw_a_e_h.xbm | 77 - hacks/images/jigsaw/jigsaw_a_f.xbm | 96 - hacks/images/jigsaw/jigsaw_a_h.xbm | 96 - hacks/images/jigsaw/jigsaw_a_n_f.xbm | 91 - hacks/images/jigsaw/jigsaw_a_n_h.xbm | 91 - hacks/images/jigsaw/jigsaw_a_ne_f.xbm | 79 - hacks/images/jigsaw/jigsaw_a_ne_h.xbm | 79 - hacks/images/jigsaw/jigsaw_a_nw_f.xbm | 73 - hacks/images/jigsaw/jigsaw_a_nw_h.xbm | 73 - hacks/images/jigsaw/jigsaw_a_s_f.xbm | 91 - hacks/images/jigsaw/jigsaw_a_s_h.xbm | 91 - hacks/images/jigsaw/jigsaw_a_se_f.xbm | 73 - hacks/images/jigsaw/jigsaw_a_se_h.xbm | 73 - hacks/images/jigsaw/jigsaw_a_sw_f.xbm | 73 - hacks/images/jigsaw/jigsaw_a_sw_h.xbm | 73 - hacks/images/jigsaw/jigsaw_a_w_f.xbm | 77 - hacks/images/jigsaw/jigsaw_a_w_h.xbm | 77 - hacks/images/jigsaw/jigsaw_b_e_f.xbm | 95 - hacks/images/jigsaw/jigsaw_b_e_h.xbm | 95 - hacks/images/jigsaw/jigsaw_b_f.xbm | 95 - hacks/images/jigsaw/jigsaw_b_h.xbm | 95 - hacks/images/jigsaw/jigsaw_b_n_f.xbm | 79 - hacks/images/jigsaw/jigsaw_b_n_h.xbm | 79 - hacks/images/jigsaw/jigsaw_b_ne_f.xbm | 79 - hacks/images/jigsaw/jigsaw_b_ne_h.xbm | 79 - hacks/images/jigsaw/jigsaw_b_nw_f.xbm | 79 - hacks/images/jigsaw/jigsaw_b_nw_h.xbm | 79 - hacks/images/jigsaw/jigsaw_b_s_f.xbm | 79 - hacks/images/jigsaw/jigsaw_b_s_h.xbm | 79 - hacks/images/jigsaw/jigsaw_b_se_f.xbm | 79 - hacks/images/jigsaw/jigsaw_b_se_h.xbm | 79 - hacks/images/jigsaw/jigsaw_b_sw_f.xbm | 79 - hacks/images/jigsaw/jigsaw_b_sw_h.xbm | 79 - hacks/images/jigsaw/jigsaw_b_w_f.xbm | 95 - hacks/images/jigsaw/jigsaw_b_w_h.xbm | 95 - hacks/images/noseguy/nose-f1.xpm | 14 +- hacks/images/noseguy/nose-f2.xpm | 14 +- hacks/images/noseguy/nose-f3.xpm | 14 +- hacks/images/noseguy/nose-f4.xpm | 12 +- hacks/images/noseguy/nose-l1.xpm | 14 +- hacks/images/noseguy/nose-l2.xpm | 14 +- hacks/images/noseguy/nose-r1.xpm | 14 +- hacks/images/noseguy/nose-r2.xpm | 14 +- hacks/images/sball-bg.xpm | 700 +- hacks/images/tunnel0.xpm | 56 +- hacks/imsmap.c | 694 +- hacks/imsmap.man | 11 +- hacks/interaggregate.c | 315 +- hacks/interaggregate.man | 2 +- hacks/interference.c | 83 +- hacks/intermomentary.c | 430 +- hacks/intermomentary.man | 8 +- hacks/jigsaw.c | 1090 +- hacks/juggle.c | 290 +- hacks/julia.c | 37 +- hacks/kaleidescope.c | 327 +- hacks/kumppa.c | 838 +- hacks/laser.c | 37 +- hacks/lightning.c | 35 +- hacks/lisa.c | 50 +- hacks/lissie.c | 47 +- hacks/lmorph.c | 471 +- hacks/loop.c | 72 +- hacks/maze.c | 1571 +- hacks/memscroller.c | 273 +- hacks/metaballs.c | 439 +- hacks/mismunch.c | 277 +- hacks/moire.c | 274 +- hacks/moire2.c | 369 +- hacks/mountain.c | 40 +- hacks/munch.c | 338 +- hacks/nerverot.c | 918 +- hacks/noseguy.c | 584 +- hacks/pacman.c | 214 +- hacks/pacman.h | 70 +- hacks/pacman_ai.c | 4 +- hacks/pacman_level.c | 116 +- hacks/pacman_level.h | 16 +- hacks/pedal.c | 261 +- hacks/pedal.man | 8 +- hacks/penetrate.c | 676 +- hacks/penrose.c | 90 +- hacks/petri.c | 537 +- hacks/phosphor.c | 435 +- hacks/piecewise.c | 573 +- hacks/polyominoes.c | 201 +- hacks/pong.c | 444 +- hacks/pong.man | 11 +- hacks/popsquares.c | 272 +- hacks/pyro.c | 253 +- hacks/qix.c | 460 +- hacks/rd-bomb.c | 549 +- hacks/ripples.c | 794 +- hacks/rocks.c | 451 +- hacks/rorschach.c | 196 +- hacks/rotor.c | 46 +- hacks/rotzoomer.c | 682 +- hacks/screenhack.c | 676 +- hacks/screenhack.h | 123 +- hacks/screenhackI.h | 131 + hacks/shadebobs.c | 369 +- hacks/sierpinski.c | 34 +- hacks/slidescreen.c | 461 +- hacks/slip.c | 98 +- hacks/sonar.c | 705 +- hacks/sonar.man | 19 +- hacks/speedmine.c | 1157 +- hacks/sphere.c | 34 +- hacks/spiral.c | 38 +- hacks/spotlight.c | 281 +- hacks/squiral.c | 264 +- hacks/starfish.c | 360 +- hacks/starfish.man | 11 +- hacks/strange.c | 42 +- hacks/substrate.c | 397 +- hacks/swirl.c | 40 +- hacks/t3d.c | 932 +- hacks/thornbird.c | 43 +- hacks/triangle.c | 28 +- hacks/truchet.c | 636 +- hacks/twang.c | 583 +- hacks/vermiculate.c | 1021 +- hacks/vines.c | 47 +- hacks/wander.c | 292 +- hacks/webcollage | 67 +- hacks/whirlwindwarp.c | 499 +- hacks/whirlygig.c | 887 +- hacks/worm.c | 26 +- hacks/wormhole.c | 306 +- hacks/xanalogtv.c | 421 +- hacks/xflame.c | 575 +- hacks/xjack.c | 763 +- hacks/xlock_23.h | 192 - hacks/xlockmore.c | 471 +- hacks/xlockmore.h | 164 +- hacks/xlockmoreI.h | 81 +- hacks/xlyap.c | 2863 +- hacks/xmatrix.c | 1803 +- hacks/xmatrix.man | 49 +- hacks/xpm-pixmap.c | 86 +- hacks/xpm-pixmap.h | 5 +- hacks/xrayswarm.c | 1079 +- hacks/xspirograph.c | 325 +- hacks/xsublim.c | 99 +- hacks/xteevee.c | 433 - hacks/xteevee.man | 130 - hacks/zoom.c | 228 +- po/POTFILES.in | 9 +- po/ca.po | 2903 +- po/da.po | 5966 +-- po/de.po | 3307 +- po/es.po | 3288 +- po/et.po | 2922 +- po/fi.po | 2924 +- po/fr.po | 4728 +- po/hu.po | 2797 +- po/it.po | 5610 +-- po/ja.po | 3329 +- po/ko.po | 3065 +- po/nb.po | 3089 +- po/nl.po | 3320 +- po/no.po | 3089 +- po/pl.po | 3159 +- po/pt.po | 3282 +- po/pt_BR.po | 2903 +- po/ru.po | 3012 +- po/sk.po | 2987 +- po/sv.po | 3144 +- po/vi.po | 3263 +- po/wa.po | 2960 +- po/zh_CN.po | 3063 +- po/zh_TW.po | 3048 +- setup.com | 2 - utils/Makefile.in | 11 +- utils/alpha.c | 4 +- utils/colorbars.c | 8 +- utils/colors.c | 2 + utils/compile_axp.com | 1 + utils/compile_decc.com | 1 + utils/erase.c | 1459 +- utils/erase.h | 6 +- utils/grabclient.c | 402 +- utils/grabscreen.c | 6 +- utils/grabscreen.h | 60 +- utils/logo.c | 181 +- utils/minixpm.c | 233 + utils/minixpm.h | 28 + utils/resources.c | 59 +- utils/resources.h | 16 +- utils/usleep.c | 2 + utils/utils.h | 11 +- utils/version.h | 2 +- utils/visual.c | 5 +- utils/visual.h | 4 +- utils/xdbe.c | 5 +- utils/xshm.c | 4 +- xscreensaver.spec | 43 +- xscreensaver.xcodeproj/project.pbxproj | 35853 ++++++++++++++++ 777 files changed, 148540 insertions(+), 88448 deletions(-) create mode 100644 OSX/._XScreenSaver.icns create mode 100644 OSX/._bindist-DS_Store create mode 100644 OSX/AppController.h create mode 100644 OSX/AppController.m create mode 100644 OSX/English.lproj/InfoPlist.strings create mode 100644 OSX/English.lproj/MainMenu.nib/classes.nib create mode 100644 OSX/English.lproj/MainMenu.nib/info.nib create mode 100644 OSX/English.lproj/MainMenu.nib/keyedobjects.nib create mode 100644 OSX/InvertedSlider.h create mode 100644 OSX/InvertedSlider.m create mode 100644 OSX/Makefile create mode 100644 OSX/PrefsReader.h create mode 100644 OSX/PrefsReader.m create mode 100644 OSX/README create mode 100644 OSX/SaverTester.plist create mode 100644 OSX/XScreenSaver.icns create mode 100644 OSX/XScreenSaver.plist create mode 100644 OSX/XScreenSaverConfigSheet.h create mode 100644 OSX/XScreenSaverConfigSheet.m create mode 100644 OSX/XScreenSaverDMG.icns create mode 100644 OSX/XScreenSaverGLView.h create mode 100644 OSX/XScreenSaverGLView.m create mode 100644 OSX/XScreenSaverSubclass.m create mode 100644 OSX/XScreenSaverView.h create mode 100644 OSX/XScreenSaverView.m create mode 100644 OSX/bindist-DS_Store create mode 100644 OSX/bindist.rtf create mode 100644 OSX/jwxyz-timers.h create mode 100644 OSX/jwxyz-timers.m create mode 100644 OSX/jwxyz.h create mode 100644 OSX/jwxyz.m create mode 100644 OSX/main.m create mode 100644 OSX/osxgrabscreen.m create mode 100755 OSX/update-info-plist.pl create mode 100644 OSX/xscreensaver_Prefix.pch delete mode 100644 README.debugging create mode 100644 README.hacking mode change 100644 => 100755 config.sub create mode 100644 driver/exec.h create mode 100644 hacks/change_locale.h create mode 100644 hacks/config/dnalogo.xml create mode 100644 hacks/config/glschool.xml create mode 100644 hacks/config/rdbomb.xml delete mode 100644 hacks/config/ssystem.xml create mode 100644 hacks/config/topblock.xml delete mode 100644 hacks/config/xearth.xml delete mode 100644 hacks/config/xfishtank.xml create mode 100644 hacks/glx/dnalogo.c create mode 100644 hacks/glx/extrusion.h create mode 100644 hacks/glx/glschool.c create mode 100644 hacks/glx/glschool.h create mode 100644 hacks/glx/glschool.man create mode 100644 hacks/glx/glschool_alg.c create mode 100644 hacks/glx/glschool_alg.h create mode 100644 hacks/glx/glschool_gl.c create mode 100644 hacks/glx/glschool_gl.h create mode 100755 hacks/glx/molecules.sh create mode 100644 hacks/glx/sproingies.h create mode 100644 hacks/glx/stonerview.h create mode 100644 hacks/glx/topblock.c create mode 100644 hacks/glx/topblock.h create mode 100644 hacks/glx/topblock.man rename hacks/glx/{xlock-gl.c => xlock-gl-utils.c} (79%) create mode 100644 hacks/images/6x10font.xbm create mode 100644 hacks/images/apple2font.xbm delete mode 100644 hacks/images/jigsaw/jigsaw.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_e_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_e_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_n_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_n_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_ne_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_ne_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_nw_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_nw_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_s_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_s_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_se_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_se_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_sw_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_sw_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_w_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_a_w_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_e_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_e_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_n_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_n_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_ne_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_ne_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_nw_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_nw_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_s_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_s_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_se_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_se_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_sw_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_sw_h.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_w_f.xbm delete mode 100644 hacks/images/jigsaw/jigsaw_b_w_h.xbm create mode 100644 hacks/screenhackI.h mode change 100755 => 100644 hacks/xflame.c delete mode 100644 hacks/xlock_23.h delete mode 100644 hacks/xteevee.c delete mode 100644 hacks/xteevee.man create mode 100644 utils/minixpm.c create mode 100644 utils/minixpm.h create mode 100644 xscreensaver.xcodeproj/project.pbxproj diff --git a/Makefile.in b/Makefile.in index 2ae53caf..12ab264a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -7,16 +7,19 @@ VPATH = @srcdir@ SHELL = /bin/sh SUBDIRS = utils driver hacks hacks/glx po -TARFILES = README README.VMS README.debugging INSTALL \ +SUBDIRS2 = $(SUBDIRS) OSX +TARFILES = README README.hacking README.VMS INSTALL \ configure configure.in Makefile.in config.h.in \ config.h-vms install-sh setup.com config.guess aclocal.m4 \ config.sub makevms.com \ intltool-merge.in intltool-extract.in intltool-update.in \ xscreensaver.spec \ + xscreensaver.xcodeproj/project.pbxproj TAR = tar -MAKE_SUBDIR = for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) $@) || exit 5; done +MAKE_SUBDIR = for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) $@) || exit 5; done +MAKE_SUBDIR2 = for dir in $(SUBDIRS2);do (cd $$dir; $(MAKE) $@) || exit 5; done default:: @$(MAKE_SUBDIR) @@ -40,17 +43,19 @@ depend:: @$(MAKE_SUBDIR) distdepend:: @$(MAKE) update_spec_version - @$(MAKE_SUBDIR) + @$(MAKE_SUBDIR2) @cd po ; $(MAKE) generate_potfiles_in TAGS:: tags tags:: @$(MAKE_SUBDIR) + clean:: - @$(MAKE_SUBDIR) + @$(MAKE_SUBDIR2) + distclean:: clean -rm -f config.h Makefile config.status config.cache config.log TAGS *~ "#"* intltool-extract intltool-merge intltool-update - @$(MAKE_SUBDIR) + @$(MAKE_SUBDIR2) dist:: tar @@ -60,14 +65,13 @@ tar:: sh config.status ; \ rm -f configure ; \ $(MAKE) configure ; \ - $(MAKE) distdepend ; \ - NAME=`sed -n \ - 's/[^0-9]*\([0-9]\.[0-9][0-9]*[0-9]*\).*/xscreensaver-\1/p' \ - utils/version.h` ; \ + $(MAKE) version-date distdepend ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h` ; \ + NAME="xscreensaver-$$VERS" ; \ rm -rf $$NAME ; ln -s . $$NAME ; \ FILES= ; \ ADIR=archive/ ; \ - for subdir in $(SUBDIRS) ; do \ + for subdir in $(SUBDIRS2) ; do \ d=`pwd` ; \ cd $$subdir ; \ FILES="$$FILES `$(MAKE) echo_tarfiles \ @@ -160,6 +164,22 @@ bump_version:: bump-version tick-version:: bump-version tick_version:: bump-version +version-date:: + @ \ + SRC=utils/version.h ; \ + D=`date '+%d-%b-%Y'`; \ + TMP=/tmp/bv.$$ ; \ + sed -e "s/([0-9][^()]*)/($$D)/" < $$SRC > $$TMP ; \ + echo -n "Updating date in $$SRC to \"$$D\"... " ; \ + if cmp -s $$SRC $$TMP ; then \ + echo "unchanged." ; \ + else \ + cat $$TMP > $$SRC ; \ + echo "done." ; \ + fi ; \ + rm -f $$TMP + + update_spec_version:: @S=$(srcdir)/xscreensaver.spec ; \ U=$(srcdir)/utils/version.h ; \ @@ -208,7 +228,7 @@ rpm:: test-tar:: @ \ - VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h` ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h` ; \ D=xscreensaver-$$VERS ; \ ADIR=archive/ ; \ NAME="$${ADIR}$$D.tar.gz" ; \ @@ -254,21 +274,30 @@ test-tar:: \ chmod -R u+w . +dmg:: + cd OSX ; $(MAKE) release dmg www:: @ \ DEST=$$HOME/www/xscreensaver ; \ - VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h` ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h` ; \ HEAD="xscreensaver-$$VERS" ; \ ADIR=archive/ ; \ BNAME="$$HEAD.tar.gz" ; \ NAME="$$ADIR$$BNAME" ; \ DNAME="$$DEST/$$HEAD.tar.gz" ; \ + BNAME2="$$HEAD.dmg" ; \ + NAME2="$$ADIR$$BNAME2" ; \ + DNAME2="$$DEST/$$HEAD.dmg" ; \ \ if [ ! -f $$NAME ]; then \ echo "$$NAME does not exist! Did you forget to \`make tar'?" ; \ exit 1 ; \ fi ; \ + if [ ! -f $$NAME2 ]; then \ + echo "$$NAME2 does not exist! Did you forget to \`make dmg'?" ; \ + exit 1 ; \ + fi ; \ chmod a-w $$NAME ; \ if [ -f $$DNAME ]; then \ echo -n "WARNING: $$DNAME already exists! Overwrite? "; \ @@ -277,12 +306,20 @@ www:: exit 1 ; \ fi ; \ fi ; \ + if [ -f $$DNAME2 ]; then \ + echo -n "WARNING: $$DNAME2 already exists! Overwrite? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + fi ; \ cp -p $$NAME $$DNAME ; \ - chmod u+w $$DNAME ; \ + cp -p $$NAME2 $$DNAME2 ; \ + chmod u+w $$DNAME $$DNAME2 ; \ cd $$DEST ; \ \ TMP=/tmp/xd.$$$$ ; \ - sed "s/xscreensaver-[0-9]\.[0-9][0-9]*/$$HEAD/g" download.html > $$TMP ; \ + sed "s/xscreensaver-5\.[0-9][0-9ab]*/$$HEAD/g" download.html > $$TMP ; \ echo '' ; \ diff -U0 download.html $$TMP ; \ echo '' ; \ @@ -297,11 +334,12 @@ www:: else \ set -x ; \ fi ; \ - cvs add -kb $$BNAME ; \ +true cvs add -kb $$BNAME $$BNAME2 ; \ cat $$TMP > download.html ; \ rm -f $$TMP ; \ \ - (cd ..; $(MAKE) xscreensaver/changelog.html ); \ + (cd ..; $(MAKE) xscreensaver/changelog.html \ + xscreensaver/screenshots/index.html ); \ cvs diff -U0 changelog.html ; \ set +x ; \ \ diff --git a/OSX/._XScreenSaver.icns b/OSX/._XScreenSaver.icns new file mode 100644 index 0000000000000000000000000000000000000000..efc1fbf027c2420b1a311c59a152b8afa289a35c GIT binary patch literal 39555 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 D$hW*A literal 0 HcmV?d00001 diff --git a/OSX/._bindist-DS_Store b/OSX/._bindist-DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..309d9026e510bca4a1ea6fd70b9bfa655e16b255 GIT binary patch literal 82 xcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4Dn2M!GXfdI~hGXP + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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. + */ + +#import +#import + +@interface AppController : NSObject +{ + ScreenSaverView *saverView0; + ScreenSaverView *saverView1; +} + +@end diff --git a/OSX/AppController.m b/OSX/AppController.m new file mode 100644 index 00000000..76911b3a --- /dev/null +++ b/OSX/AppController.m @@ -0,0 +1,200 @@ +/* xscreensaver, Copyright (c) 2006 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. + */ + +/* This is just a test harness, really -- it makes a window with an + XScreenSaverGLView in it and a Preferences button, because I don't want + to have to debug these programs by installing them as screen savers + first! + */ + +#import "AppController.h" +#import "XScreenSaverGLView.h" + +@implementation AppController + +- (ScreenSaverView *) makeSaverView +{ + const char *var = "SCREENSAVER_MODULE"; + const char *s = getenv (var); + if (!s || !*s) { + NSAssert1 (0, @"set $%s to the name of the module to run", var); + exit(1); + } + NSString *module = [NSString stringWithCString:s + encoding:NSUTF8StringEncoding]; + NSString *dir = [[[NSBundle mainBundle] bundlePath] + stringByDeletingLastPathComponent]; + NSString *name = [module stringByAppendingPathExtension:@"saver"]; + NSString *path = [dir stringByAppendingPathComponent:name]; + NSBundle *bundleToLoad = [NSBundle bundleWithPath:path]; + Class new_class = [bundleToLoad principalClass]; + NSAssert1 (new_class, @"unable to load \"%@\"", path); + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = 320; + rect.size.height = 240; + + id instance = [[new_class alloc] initWithFrame:rect isPreview:YES]; + NSAssert1 (instance, @"unable to instantiate %@", new_class); + return (ScreenSaverView *) instance; +} + + +- (void) openPreferences: (int) which +{ + ScreenSaverView *sv = (which ? saverView1 : saverView0); + NSAssert (sv, @"no saver view"); + NSWindow *prefs = [sv configureSheet]; + + [NSApp beginSheet:prefs + modalForWindow:[sv window] + modalDelegate:self + didEndSelector:@selector(preferencesClosed:returnCode:contextInfo:) + contextInfo:nil]; + int code = [NSApp runModalForWindow:prefs]; + + /* Restart the animation if the "OK" button was hit, but not if "Cancel". + We have to restart *both* animations, because the xlockmore-style + ones will blow up if one re-inits but the other doesn't. + */ + if (code != NSCancelButton) { + if (saverView0) [saverView0 stopAnimation]; + if (saverView1) [saverView1 stopAnimation]; + if (saverView0) [saverView0 startAnimation]; + if (saverView1) [saverView1 startAnimation]; + } +} + +- (void) openPreferences0: (NSObject *) button +{ + [self openPreferences:0]; +} + +- (void) openPreferences1: (NSObject *) button +{ + [self openPreferences:1]; +} + +- (void) preferencesClosed: (NSWindow *) sheet + returnCode: (int) returnCode + contextInfo: (void *) contextInfo +{ + [NSApp stopModalWithCode:returnCode]; +} + + +- (void) makeWindow: (ScreenSaverView *)sv which:(int)which +{ + NSRect rect; + + if (which) + saverView1 = sv; + else + saverView0 = sv; + + // make a "Preferences" button + // + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + NSButton *pb = [[NSButton alloc] initWithFrame:rect]; + [pb setTitle:@"Preferences"]; + [pb setBezelStyle:NSRoundedBezelStyle]; + [pb sizeToFit]; + rect.origin.x = ([sv frame].size.width - + [pb frame].size.width) / 2; + [pb setFrameOrigin:rect.origin]; + + // grab the click + // + [pb setTarget:self]; + if (which) + [pb setAction:@selector(openPreferences1:)]; + else + [pb setAction:@selector(openPreferences0:)]; + + // make a box to wrap the saverView + // + rect = [sv frame]; + rect.origin.x = 0; + rect.origin.y = [pb frame].origin.y + [pb frame].size.height; + NSBox *gbox = [[NSBox alloc] initWithFrame:rect]; + rect.size.width = rect.size.height = 10; + [gbox setContentViewMargins:rect.size]; + [gbox setTitlePosition:NSNoTitle]; + [gbox addSubview:sv]; + [gbox sizeToFit]; + + // make a box to wrap the other two boxes + // + rect.origin.x = rect.origin.y = 0; + rect.size.width = [gbox frame].size.width; + rect.size.height = [gbox frame].size.height + [gbox frame].origin.y; + NSBox *pbox = [[NSBox alloc] initWithFrame:rect]; + [pbox setTitlePosition:NSNoTitle]; + [pbox setBorderType:NSNoBorder]; + [pbox addSubview:gbox]; + [pbox addSubview:pb]; + [pbox sizeToFit]; + + // and make a window to hold that. + // + NSScreen *screen = [NSScreen mainScreen]; + rect = [pbox frame]; + rect.origin.x = ([screen frame].size.width - rect.size.width) / 2; + rect.origin.y = ([screen frame].size.height - rect.size.height) / 2; + + rect.origin.x += rect.size.width * (which ? 0.55 : -0.55); + + NSWindow *window = [[NSWindow alloc] + initWithContentRect:rect + styleMask:(NSTitledWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask) + backing:NSBackingStoreBuffered + defer:YES + screen:screen]; + [window setTitle:@"XScreenSaver"]; + [window setMinSize:[window frameRectForContentRect:rect].size]; + + [[window contentView] addSubview:pbox]; + + [sv setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + [pb setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; + [gbox setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + [pbox setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + + [window setFrameAutosaveName:(which + ? @"SaverDebugWindow1" + : @"SaverDebugWindow0")]; + [window setFrameUsingName:[window frameAutosaveName]]; + + [window makeKeyAndOrderFront:window]; + + [sv startAnimation]; +} + + +- (void)applicationDidFinishLaunching: (NSNotification *) n +{ + [self makeWindow:[self makeSaverView] which:0]; + [self makeWindow:[self makeSaverView] which:1]; +} + +/* When the window closes, exit (even if prefs still open.) +*/ +- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *) n +{ + return YES; +} + +@end diff --git a/OSX/English.lproj/InfoPlist.strings b/OSX/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..dea12de4cad936a6204d4da70d2ca96aef900b31 GIT binary patch literal 92 zcmW-Z!3uyN5C!M#S9tbN-x2r|Q3;V~qzLu#)x*oq?lA28G2*azG7B@2orjH8u89{# bCX+-f2F*!V&^~bXzEEWk)pxI)ej3aVcM}l{ literal 0 HcmV?d00001 diff --git a/OSX/English.lproj/MainMenu.nib/classes.nib b/OSX/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 00000000..cbc6c754 --- /dev/null +++ b/OSX/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,9 @@ +{ + IBClasses = ( + {CLASS = AppController; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = InvertedSlider; LANGUAGE = ObjC; SUPERCLASS = NSSlider; }, + {CLASS = PrefsReader; LANGUAGE = ObjC; SUPERCLASS = NSObject; } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/OSX/English.lproj/MainMenu.nib/info.nib b/OSX/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 00000000..a3bd34e1 --- /dev/null +++ b/OSX/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 135 107 356 240 0 0 1680 1028 + IBEditorPositions + + 29 + 132 353 321 44 0 0 1680 1028 + + IBFramework Version + 443.0 + IBOpenObjects + + 29 + + IBSystem Version + 8G32 + + diff --git a/OSX/English.lproj/MainMenu.nib/keyedobjects.nib b/OSX/English.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..e6c5e48add7b89c7bbfdaaf8a809dda9476b3e70 GIT binary patch literal 11645 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 G5dD8jcABaH literal 0 HcmV?d00001 diff --git a/OSX/InvertedSlider.h b/OSX/InvertedSlider.h new file mode 100644 index 00000000..71efb161 --- /dev/null +++ b/OSX/InvertedSlider.h @@ -0,0 +1,20 @@ +/* xscreensaver, Copyright (c) 2006 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. +* +* This is a subclass of NSSlider that is flipped horizontally: +* the high value is on the left and the low value is on the right. +*/ + +#import + +@interface InvertedSlider : NSSlider +{ +} +@end diff --git a/OSX/InvertedSlider.m b/OSX/InvertedSlider.m new file mode 100644 index 00000000..d291ffec --- /dev/null +++ b/OSX/InvertedSlider.m @@ -0,0 +1,102 @@ +/* xscreensaver, Copyright (c) 2006 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. +* +* This is a subclass of NSSlider that is flipped horizontally: +* the high value is on the left and the low value is on the right. +*/ + +#import "InvertedSlider.h" + +@implementation InvertedSlider + +-(double) transformValue:(double) value +{ + double low = [self minValue]; + double high = [self maxValue]; + double range = high - low; + double off = value - low; + double trans = low + (range - off); + // NSLog (@" ... %.1f -> %.1f [%.1f - %.1f]\n", value, trans, low, high); + return trans; +} + +-(double) doubleValue; +{ + return [self transformValue:[super doubleValue]]; +} + +-(void) setDoubleValue:(double)v +{ + return [super setDoubleValue:[self transformValue:v]]; +} + + +/* Implement all accessor methods in terms of "doubleValue" above. + */ + +-(float) floatValue; +{ + return (float) [self doubleValue]; +} + +-(int) intValue; +{ + return (int) [self doubleValue]; +} + +-(id) objectValue; +{ + return [NSNumber numberWithDouble:[self doubleValue]]; +} + +-(NSString *) stringValue; +{ + return [NSString stringWithFormat:@"%f", [self floatValue]]; +} + +- (NSAttributedString *)attributedStringValue; +{ + return [[NSAttributedString alloc] initWithString:[self stringValue]]; +} + + +/* Implment all setter methods in terms of "setDoubleValue", above. + */ + +-(void) setFloatValue:(double)v +{ + [self setDoubleValue:(double)v]; +} + +-(void) setIntValue:(int)v +{ + [self setDoubleValue:(double)v]; +} + +-(void) setObjectValue:(id )v +{ + NSAssert2((v == nil) || + [(NSObject *) v respondsToSelector:@selector(doubleValue)], + @"argument %@ to %s does not respond to doubleValue", + v, __PRETTY_FUNCTION__); + [self setDoubleValue:[((NSNumber *) v) doubleValue]]; +} + +-(void) setStringValue:(NSString *)v +{ + [self setDoubleValue:[v doubleValue]]; +} + +-(void) setAttributedStringValue:(NSAttributedString *)v +{ + [self setStringValue:[v string]]; +} + +@end diff --git a/OSX/Makefile b/OSX/Makefile new file mode 100644 index 00000000..f57fcb1c --- /dev/null +++ b/OSX/Makefile @@ -0,0 +1,92 @@ +# XScreenSaver for MacOS X, Copyright (c) 2006 by Jamie Zawinski. + +XCODE_TARGET = "All Savers" + +default: release +all: debug release + +clean: + -rm -rf build +# cd ..; xcodebuild -target $(XCODE_TARGET) clean + +distclean: + -rm -f config.status config.cache config.log \ + *.bak *.rej TAGS *~ "#"* + -rm -rf autom4te*.cache + -rm -rf build + +distdepend:: update_plist_version + +debug: + cd ..; xcodebuild -target $(XCODE_TARGET) -configuration Debug build + +release: + cd ..; xcodebuild -target $(XCODE_TARGET) -configuration Release build + +echo_tarfiles: + @echo `find . \ + \( \( -name '.??*' -o -name build -o -name CVS -o -name '*~*' \ + -o -name 'jwz.*' \) \ + -prune \) \ + -o -type f -print \ + | sed 's@^\./@@' \ + | sort` + +update_plist_version: + @ \ + SRC=../utils/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' $$SRC` ; \ + T=/tmp/xs.$$$$ ; \ + for S in XScreenSaver.plist SaverTester.plist ; do \ + echo -n "Updating version number in $$S to \"$$V\"... " ; \ + KEYS="CFBundleVersion|CFBundleShortVersionString" ; \ + perl -0777 -pne \ + "s@(($$KEYS)\s*)[^<>]+()@\$${1}$$V\$${3}@g" \ + < $$S > $$T ; \ + if cmp -s $$S $$T ; then \ + echo "unchanged." ; \ + else \ + cat $$T > $$S ; \ + echo "done." ; \ + fi ; \ + done ; \ + rm $$T + +# -format UDBZ saves 4% (~1.2 MB) over UDZO. +dmg:: + @ \ + set -e ; \ + SRC=../utils/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' $$SRC` ; \ + TMPDIR="build" ; \ + SRC="build/Release" ; \ + BASE="xscreensaver-$$V" ; \ + OUTDIR="../archive" ; \ + DMG="$$OUTDIR/$$BASE.dmg" ; \ + TMPDMG="$$TMPDIR/tmp.dmg" ; \ + VOLNAME="XScreenSaver $$V" ; \ + STAGE="$$TMPDIR/dmg_stage" ; \ + rm -f "$$DMG" ; \ + rm -rf "$$STAGE" ; \ + echo + mkdir "$$STAGE" ; \ + mkdir "$$STAGE" ; \ + echo + cp -pr "$$SRC/"\*.saver "$$STAGE" ; \ + cp -pr "$$SRC/"*.saver "$$STAGE" ; \ + set -x ; \ + cp -p bindist.rtf "$$STAGE/ READ ME.rtf" ; \ + cp -p bindist-DS_Store "$$STAGE/.DS_Store" ; \ + cp -p XScreenSaverDMG.icns "$$STAGE/.VolumeIcon.icns" ; \ + /Developer/Tools/SetFile -a C "$$STAGE" ; \ + /Developer/Tools/SetFile -a E "$$STAGE/ READ ME.rtf" ; \ + hdiutil makehybrid -quiet -ov -hfs -hfs-volume-name "$$VOLNAME" \ + -hfs-openfolder "$$STAGE" "$$STAGE" -o "$$TMPDMG" ; \ + rm -rf "$$STAGE" ; \ + hdiutil convert -quiet -ov -format UDBZ -imagekey zlib-level=9 \ + "$$TMPDMG" -o "$$DMG" ; \ + rm -f "$$TMPDMG" ; \ + ls -ldhgF "$$DMG" + +# Adding this is cute: +# hdiutil internet-enable -yes -quiet "$$DMG" +# but means that nobody will ever see the display settings I used! +# When finder copies the .dmg to a folder, it doesn't preserve them. diff --git a/OSX/PrefsReader.h b/OSX/PrefsReader.h new file mode 100644 index 00000000..9905aeb0 --- /dev/null +++ b/OSX/PrefsReader.h @@ -0,0 +1,39 @@ +/* xscreensaver, Copyright (c) 2006 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. + */ + +/* This implements the substrate of the xscreensaver preferences code: + It does this by writing defaults to, and reading values from, the + NSUserDefaultsController (and ScreenSaverDefaults/NSUserDefaults) + and thereby reading the preferences that may have been edited by + the UI (XScreenSaverConfigSheet). + */ + +#import +#import "jwxyz.h" + +@interface PrefsReader : NSObject +{ + NSUserDefaultsController *userDefaultsController; + NSUserDefaults *userDefaults; // this is actually a 'ScreenSaverDefaults' +} + +- (id) initWithName: (NSString *) name + xrmKeys: (const XrmOptionDescRec *) opts + defaults: (const char * const *) defs; + +- (NSUserDefaultsController *) userDefaultsController; + +- (char *) getStringResource: (const char *) name; +- (double) getFloatResource: (const char *) name; +- (int) getIntegerResource: (const char *) name; +- (BOOL) getBooleanResource: (const char *) name; + +@end diff --git a/OSX/PrefsReader.m b/OSX/PrefsReader.m new file mode 100644 index 00000000..3c20f3dc --- /dev/null +++ b/OSX/PrefsReader.m @@ -0,0 +1,283 @@ +/* xscreensaver, Copyright (c) 2006 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. + */ + +/* This implements the substrate of the xscreensaver preferences code: + It does this by writing defaults to, and reading values from, the + NSUserDefaultsController (and ScreenSaverDefaults/NSUserDefaults) + and thereby reading the preferences that may have been edited by + the UI (XScreenSaverConfigSheet). + */ + +#import +#import "PrefsReader.h" +#import "screenhackI.h" + +@implementation PrefsReader + +/* Converts an array of "key:value" strings to an NSDictionary. + */ +- (NSDictionary *) defaultsToDict: (const char * const *) defs +{ + NSDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:20]; + while (*defs) { + char *line = strdup (*defs); + char *key, *val; + key = line; + while (*key == '.' || *key == '*' || *key == ' ' || *key == '\t') + key++; + val = key; + while (*val && *val != ':') + val++; + if (*val != ':') abort(); + *val++ = 0; + while (*val == ' ' || *val == '\t') + val++; + + int L = strlen(val); + while (L > 0 && (val[L-1] == ' ' || val[L-1] == '\t')) + val[--L] = 0; + + // When storing into preferences, look at the default string and + // decide whether it's a boolean, int, float, or string, and store + // an object of the appropriate type in the prefs. + // + NSString *nskey = [NSString stringWithCString:key + encoding:NSUTF8StringEncoding]; + NSObject *nsval; + int dd; + double ff; + char cc; + if (!strcasecmp (val, "true") || !strcasecmp (val, "yes")) + nsval = [NSNumber numberWithBool:YES]; + else if (!strcasecmp (val, "false") || !strcasecmp (val, "no")) + nsval = [NSNumber numberWithBool:NO]; + else if (1 == sscanf (val, " %d %c", &dd, &cc)) + nsval = [NSNumber numberWithInt:dd]; + else if (1 == sscanf (val, " %lf %c", &ff, &cc)) + nsval = [NSNumber numberWithDouble:ff]; + else + nsval = [NSString stringWithCString:val encoding:NSUTF8StringEncoding]; + +// NSLog (@"default: \"%@\" = \"%@\" [%@]\n", nskey, nsval, [nsval class]); + [dict setValue:nsval forKey:nskey]; + free (line); + defs++; + } + return dict; +} + + +/* Initialize the Cocoa preferences database: + - sets the default preferences values from the 'defaults' array; + - binds 'self' to each preference as an observer; + - ensures that nothing is mentioned in 'options' and not in 'defaults'; + - ensures that nothing is mentioned in 'defaults' and not in 'options'. + */ +- (void) registerXrmKeys: (const XrmOptionDescRec *) opts + defaults: (const char * const *) defs +{ + // Store the contents of 'defaults' into the real preferences database. + NSDictionary *defsdict = [self defaultsToDict:defs]; + [userDefaults registerDefaults:defsdict]; + + userDefaultsController = + [[NSUserDefaultsController alloc] initWithDefaults:userDefaults + initialValues:defsdict]; + + NSDictionary *optsdict = [NSMutableDictionary dictionaryWithCapacity:20]; + + while (opts[0].option) { + //const char *option = opts->option; + const char *resource = opts->specifier; + + while (*resource == '.' || *resource == '*') + resource++; + NSString *nsresource = [NSString stringWithCString:resource + encoding:NSUTF8StringEncoding]; + + // make sure there's no resource mentioned in options and not defaults. + if (![defsdict objectForKey:nsresource]) { + if (! (!strcmp(resource, "font") || // don't warn about these + !strcmp(resource, "textLiteral") || + !strcmp(resource, "textFile") || + !strcmp(resource, "textURL") || + !strcmp(resource, "imageDirectory"))) + NSLog (@"warning: \"%s\" is in options but not defaults", resource); + } + [optsdict setValue:nsresource forKey:nsresource]; + + opts++; + } + + // make sure there's no resource mentioned in defaults and not options. + NSEnumerator *enumerator = [defsdict keyEnumerator]; + NSString *key; + while ((key = [enumerator nextObject])) { +#if 0 + if (! [optsdict objectForKey:key]) + if (! ([key isEqualToString:@"foreground"] || // don't warn about these + [key isEqualToString:@"background"] || + [key isEqualToString:@"Background"] || + [key isEqualToString:@"geometry"] || + [key isEqualToString:@"font"] || + [key isEqualToString:@"dontClearRoot"] || + + // fps.c settings + [key isEqualToString:@"fpsSolid"] || + [key isEqualToString:@"fpsTop"] || + [key isEqualToString:@"titleFont"] || + + // analogtv.c settings + [key isEqualToString:@"TVBrightness"] || + [key isEqualToString:@"TVColor"] || + [key isEqualToString:@"TVContrast"] || + [key isEqualToString:@"TVTint"] + )) + NSLog (@"warning: \"%@\" is in defaults but not options", key); +#endif /* 0 */ + } + +} + +- (NSUserDefaultsController *) userDefaultsController +{ + NSAssert(userDefaultsController, @"userDefaultsController uninitialized"); + return userDefaultsController; +} + + +- (NSObject *) getObjectResource: (const char *) name +{ + while (1) { + NSString *key = [NSString stringWithCString:name + encoding:NSUTF8StringEncoding]; + NSObject *obj = [userDefaults objectForKey:key]; + if (obj) + return obj; + + // If key is "foo.bar.baz", check "foo.bar.baz", "bar.baz", and "baz". + // + const char *dot = strchr (name, '.'); + if (dot && dot[1]) + name = dot + 1; + else + return nil; + } +} + + +- (char *) getStringResource: (const char *) name +{ + NSObject *o = [self getObjectResource:name]; + //NSLog(@"%s = %@\n",name,o); + if (o == nil) { + if (! (!strcmp(name, "eraseMode") || // erase.c + // xlockmore.c reads all of these whether used or not... + !strcmp(name, "right3d") || + !strcmp(name, "left3d") || + !strcmp(name, "both3d") || + !strcmp(name, "none3d") || + !strcmp(name, "font") || + !strcmp(name, "labelFont") || // grabclient.c + !strcmp(name, "titleFont") || + !strcmp(name, "background") + )) + NSLog(@"warning: no preference \"%s\" [string]\n", name); + return NULL; + } +#if 0 + if (! [o isKindOfClass:[NSString class]]) { + NSAssert2(0, @"%s = \"%@\" but should have been an NSString", name, o); + abort(); + } +#else + if (! [o isKindOfClass:[NSString class]]) { + NSLog(@"asked for %s as a string, but it is a %@", name, [o class]); + o = [(NSNumber *) o stringValue]; + } +#endif + + NSString *os = (NSString *) o; + const char *result = [os cStringUsingEncoding:NSUTF8StringEncoding]; + return strdup (result); +} + + +- (double) getFloatResource: (const char *) name +{ + NSObject *o = [self getObjectResource:name]; + if (o == nil) { + // xlockmore.c reads all of these whether used or not... + if (! (!strcmp(name, "cycles") || + !strcmp(name, "size") || + !strcmp(name, "use3d") || + !strcmp(name, "delta3d") || + !strcmp(name, "wireframe") || + !strcmp(name, "showFPS") || + !strcmp(name, "fpsSolid") || + !strcmp(name, "fpsTop") || + !strcmp(name, "mono") || + !strcmp(name, "count") || + !strcmp(name, "ncolors") || + !strcmp(name, "eraseSeconds") // erase.c + )) + NSLog(@"warning: no preference \"%s\" [float]\n", name); + return 0.0; + } + if ([o isKindOfClass:[NSString class]]) { + return [(NSString *) o doubleValue]; + } else if ([o isKindOfClass:[NSNumber class]]) { + return [(NSNumber *) o doubleValue]; + } else { + NSAssert2(0, @"%s = \"%@\" but should have been an NSNumber", name, o); + abort(); + } +} + + +- (int) getIntegerResource: (const char *) name +{ + return (int) [self getFloatResource:name]; +} + + +- (BOOL) getBooleanResource: (const char *) name +{ + int n = [self getIntegerResource:name]; + if (n == 0) return NO; + else if (n == 1) return YES; + else { + NSAssert2(0, @"%s = %d but should have been 0 or 1\n", name, n); + abort(); + } +} + + +- (id) initWithName: (NSString *) name + xrmKeys: (const XrmOptionDescRec *) opts + defaults: (const char * const *) defs +{ + self = [self init]; + if (!self) return nil; + + userDefaults = [ScreenSaverDefaults defaultsForModuleWithName:name]; + + [self registerXrmKeys:opts defaults:defs]; + return self; +} + +- (void) dealloc +{ + [userDefaultsController release]; + [super dealloc]; +} + +@end diff --git a/OSX/README b/OSX/README new file mode 100644 index 00000000..4a9ea807 --- /dev/null +++ b/OSX/README @@ -0,0 +1,10 @@ + +This directory contains the MacOS-specific code for building a Cocoa +version of xscreensaver without using X11. + +To build it, just type "make", or use the included XCode project. The +executables will show up in the "build/Release/" and/or "build/Debug/" +directories. + +To build these programs, XCode 2.2 or later is required. +To run them, MacOS 10.4.0 or later is required. diff --git a/OSX/SaverTester.plist b/OSX/SaverTester.plist new file mode 100644 index 00000000..c3de714f --- /dev/null +++ b/OSX/SaverTester.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.jwz.xscreensaver.${EXECUTABLE_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 5.00 + CFBundleSignature + ???? + CFBundleVersion + 5.00 + LSMinimumSystemVersion + 10.4.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/OSX/XScreenSaver.icns b/OSX/XScreenSaver.icns new file mode 100644 index 0000000000000000000000000000000000000000..15a25c7f7432b3184ac56e8b996683bf4d036e5b GIT binary patch literal 39163 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 literal 0 HcmV?d00001 diff --git a/OSX/XScreenSaver.plist b/OSX/XScreenSaver.plist new file mode 100644 index 00000000..2fa609ae --- /dev/null +++ b/OSX/XScreenSaver.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.jwz.xscreensaver.${EXECUTABLE_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 5.00 + CFBundleSignature + ???? + CFBundleVersion + 5.00 + LSMinimumSystemVersion + 10.4.0 + NSMainNibFile + MainMenu + NSPrincipalClass + XScreenSaver${EXECUTABLE_NAME}View + + diff --git a/OSX/XScreenSaverConfigSheet.h b/OSX/XScreenSaverConfigSheet.h new file mode 100644 index 00000000..0df9d591 --- /dev/null +++ b/OSX/XScreenSaverConfigSheet.h @@ -0,0 +1,38 @@ +/* xscreensaver, Copyright (c) 2006 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. + */ + +/* XScreenSaver uses XML files to describe the user interface for configuring + the various screen savers. These files live in .../hacks/config/ and + say relatively high level things like: "there should be a checkbox + labelled "Leave Trails", and when it is checked, add the option '-trails' + to the command line when launching the program." + + This code reads that XML and constructs a Cocoa interface from it. + The Cocoa controls are hooked up to NSUserDefaultsController to save + those settings into the MacOS preferences system. The Cocoa preferences + names are the same as the resource names specified in the screenhack's + 'options' array (we use that array to map the command line switches + specified in the XML to the resource names to use). + */ + +#import +#import "jwxyz.h" + +@interface XScreenSaverConfigSheet : NSWindow +{ + NSUserDefaultsController *userDefaultsController; +} + +- (id)initWithXMLFile: (NSString *) xml_file + options: (const XrmOptionDescRec *) opts + controller: (NSUserDefaultsController *) prefs; + +@end diff --git a/OSX/XScreenSaverConfigSheet.m b/OSX/XScreenSaverConfigSheet.m new file mode 100644 index 00000000..24ab1c42 --- /dev/null +++ b/OSX/XScreenSaverConfigSheet.m @@ -0,0 +1,1748 @@ +/* xscreensaver, Copyright (c) 2006 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. + */ + +/* XScreenSaver uses XML files to describe the user interface for configuring + the various screen savers. These files live in .../hacks/config/ and + say relatively high level things like: "there should be a checkbox + labelled "Leave Trails", and when it is checked, add the option '-trails' + to the command line when launching the program." + + This code reads that XML and constructs a Cocoa interface from it. + The Cocoa controls are hooked up to NSUserDefaultsController to save + those settings into the MacOS preferences system. The Cocoa preferences + names are the same as the resource names specified in the screenhack's + 'options' array (we use that array to map the command line switches + specified in the XML to the resource names to use). + */ + +#import "XScreenSaverConfigSheet.h" + +#import "jwxyz.h" +#import "InvertedSlider.h" +#import + +@implementation XScreenSaverConfigSheet + +#define LEFT_MARGIN 20 // left edge of window +#define COLUMN_SPACING 10 // gap between e.g. labels and text fields +#define LEFT_LABEL_WIDTH 70 // width of all left labels +#define LINE_SPACING 10 // leading between each line + +// redefine these since they don't work when not inside an ObjC method +#undef NSAssert +#undef NSAssert1 +#undef NSAssert2 +#undef NSAssert3 +#define NSAssert(CC,S) do { if (!(CC)) { NSLog(S); }} while(0) +#define NSAssert1(CC,S,A) do { if (!(CC)) { NSLog(S,A); }} while(0) +#define NSAssert2(CC,S,A,B) do { if (!(CC)) { NSLog(S,A,B); }} while(0) +#define NSAssert3(CC,S,A,B,C) do { if (!(CC)) { NSLog(S,A,B,C); }} while(0) + + +/* Given a command-line option, returns the corresponding resource name. + Any arguments in the switch string are ignored (e.g., "-foo x"). + */ +static NSString * +switch_to_resource (NSString *cmdline_switch, const XrmOptionDescRec *opts, + NSString **val_ret) +{ + char buf[255]; + char *tail = 0; + NSAssert(cmdline_switch, @"cmdline switch is null"); + if (! [cmdline_switch getCString:buf maxLength:sizeof(buf) + encoding:NSUTF8StringEncoding]) { + NSAssert1(0, @"unable to convert %@\n", cmdline_switch); + abort(); + } + char *s = strpbrk(buf, " \t\r\n"); + if (s && *s) { + *s = 0; + tail = s+1; + while (*tail && (*tail == ' ' || *tail == '\t')) + tail++; + } + + while (opts[0].option) { + if (!strcmp (opts[0].option, buf)) { + const char *ret = 0; + + if (opts[0].argKind == XrmoptionNoArg) { + if (tail && *tail) + NSAssert1 (0, @"expected no args to switch: \"%@\"\n", + cmdline_switch); + ret = opts[0].value; + } else { + if (!tail || !*tail) + NSAssert1 (0, @"expected args to switch: \"%@\"\n", + cmdline_switch); + ret = tail; + } + + if (val_ret) + *val_ret = (ret + ? [NSString stringWithCString:ret + encoding:NSUTF8StringEncoding] + : 0); + + const char *res = opts[0].specifier; + while (*res && (*res == '.' || *res == '*')) + res++; + return [NSString stringWithCString:res + encoding:NSUTF8StringEncoding]; + } + opts++; + } + + NSAssert1 (0, @"\"%@\" not present in options\n", cmdline_switch); + abort(); +} + + +/* Connects a control (checkbox, etc) to the corresponding preferences key. + */ +static void +bind_resource_to_preferences (NSUserDefaultsController *prefs, + NSObject *control, + NSString *pref_key, + const XrmOptionDescRec *opts) +{ + NSString *bindto = ([control isKindOfClass:[NSPopUpButton class]] + ? @"selectedObject" + : ([control isKindOfClass:[NSMatrix class]] + ? @"selectedIndex" + : @"value")); + [control bind:bindto + toObject:prefs + withKeyPath:[@"values." stringByAppendingString: pref_key] + options:nil]; + +# if 0 // #### + NSObject *def = [[prefs defaults] objectForKey:pref_key]; + NSString *s = [NSString stringWithFormat:@"bind: \"%@\"", pref_key]; + s = [s stringByPaddingToLength:18 withString:@" " startingAtIndex:0]; + s = [NSString stringWithFormat:@"%@ = \"%@\"", s, def]; + s = [s stringByPaddingToLength:28 withString:@" " startingAtIndex:0]; + NSLog (@"%@ %@/%@\n", s, [def class], [control class]); +# endif +} + +static void +bind_switch_to_preferences (NSUserDefaultsController *prefs, + NSObject *control, + NSString *cmdline_switch, + const XrmOptionDescRec *opts) +{ + NSString *pref_key = switch_to_resource (cmdline_switch, opts, 0); + bind_resource_to_preferences (prefs, control, pref_key, opts); +} + + +/* Parse the attributes of an XML tag into a dictionary. + For input, the dictionary should have as attributes the keys, each + with @"" as their value. + On output, the dictionary will set the keys to the values specified, + and keys that were not specified will not be present in the dictionary. + Warnings are printed if there are duplicate or unknown attributes. + */ +static void +parse_attrs (NSMutableDictionary *dict, NSXMLNode *node) +{ + NSArray *attrs = [(NSXMLElement *) node attributes]; + int n = [attrs count]; + int i; + + // For each key in the dictionary, fill in the dict with the corresponding + // value. The value @"" is assumed to mean "un-set". Issue a warning if + // an attribute is specified twice. + // + for (i = 0; i < n; i++) { + NSXMLNode *attr = [attrs objectAtIndex:i]; + NSString *key = [attr name]; + NSString *val = [attr objectValue]; + NSString *old = [dict objectForKey:key]; + + if (! old) { + NSAssert2 (0, @"unknown attribute \"%@\" in \"%@\"\n", key, [node name]); + } else if ([old length] != 0) { + NSAssert2 (0, @"duplicate %@: \"%@\", \"%@\"\n", old, val); + } else { + [dict setValue:val forKey:key]; + } + } + + // Remove from the dictionary any keys whose value is still @"", + // meaning there was no such attribute specified. + // + NSArray *keys = [dict allKeys]; + n = [keys count]; + for (i = 0; i < n; i++) { + NSString *key = [keys objectAtIndex:i]; + NSString *val = [dict objectForKey:key]; + if ([val length] == 0) + [dict removeObjectForKey:key]; + } +} + + +/* Creates a label: an un-editable NSTextField displaying the given text. + */ +static NSTextField * +make_label (NSString *text) +{ + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + NSTextField *lab = [[NSTextField alloc] initWithFrame:rect]; + [lab setSelectable:NO]; + [lab setEditable:NO]; + [lab setBezeled:NO]; + [lab setDrawsBackground:NO]; + [lab setStringValue:text]; + [lab sizeToFit]; + return lab; +} + + +static NSView * +last_child (NSView *parent) +{ + NSArray *kids = [parent subviews]; + int nkids = [kids count]; + if (nkids == 0) + return 0; + else + return [kids objectAtIndex:nkids-1]; +} + + +/* Add the child as a subview of the parent, positioning it immediately + below or to the right of the previously-added child of that view. + */ +static void +place_child (NSView *parent, NSView *child, BOOL right_p) +{ + NSRect rect = [child frame]; + NSView *last = last_child (parent); + if (!last) { + rect.origin.x = LEFT_MARGIN; + rect.origin.y = [parent frame].size.height - rect.size.height + - LINE_SPACING; + } else if (right_p) { + rect = [last frame]; + rect.origin.x += rect.size.width + COLUMN_SPACING; + } else { + rect = [last frame]; + rect.origin.x = LEFT_MARGIN; + rect.origin.y -= [child frame].size.height + LINE_SPACING; + } + [child setFrameOrigin:rect.origin]; + [parent addSubview:child]; +} + + +static void traverse_children (NSUserDefaultsController *, + const XrmOptionDescRec *, + NSView *, NSXMLNode *); + + +/* Creates the checkbox (NSButton) described by the given XML node. + */ +static void +make_checkbox (NSUserDefaultsController *prefs, + const XrmOptionDescRec *opts, NSView *parent, NSXMLNode *node) +{ + NSMutableDictionary *dict = + [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"", @"id", + @"", @"_label", + @"", @"arg-set", + @"", @"arg-unset", + nil]; + parse_attrs (dict, node); + NSString *label = [dict objectForKey:@"_label"]; + NSString *arg_set = [dict objectForKey:@"arg-set"]; + NSString *arg_unset = [dict objectForKey:@"arg-unset"]; + + if (!label) { + NSAssert1 (0, @"no _label in %@\n", [node name]); + return; + } + if (!arg_set && !arg_unset) { + NSAssert1 (0, @"neither arg-set nor arg-unset provided in \"%@\"\n", + label); + } + if (arg_set && arg_unset) { + NSAssert1 (0, @"only one of arg-set and arg-unset may be used in \"%@\"\n", + label); + } + + // sanity-check the choice of argument names. + // + if (arg_set && ([arg_set hasPrefix:@"-no-"] || + [arg_set hasPrefix:@"--no-"])) + NSLog (@"arg-set should not be a \"no\" option in \"%@\": %@\n", + label, arg_set); + if (arg_unset && (![arg_unset hasPrefix:@"-no-"] && + ![arg_unset hasPrefix:@"--no-"])) + NSLog(@"arg-unset should be a \"no\" option in \"%@\": %@\n", + label, arg_unset); + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + + NSButton *button = [[NSButton alloc] initWithFrame:rect]; + [button setButtonType:([[node name] isEqualToString:@"radio"] + ? NSRadioButton + : NSSwitchButton)]; + [button setTitle:label]; + [button sizeToFit]; + place_child (parent, button, NO); + + bind_switch_to_preferences (prefs, button, + (arg_set ? arg_set : arg_unset), + opts); + [button release]; +} + + +/* Creates the NSTextField described by the given XML node. +*/ +static void +make_text_field (NSUserDefaultsController *prefs, + const XrmOptionDescRec *opts, NSView *parent, NSXMLNode *node, + BOOL no_label_p) +{ + NSMutableDictionary *dict = + [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"", @"id", + @"", @"_label", + @"", @"arg", + nil]; + parse_attrs (dict, node); + NSString *label = [dict objectForKey:@"_label"]; + NSString *arg = [dict objectForKey:@"arg"]; + + if (!label && !no_label_p) { + NSAssert1 (0, @"no _label in %@\n", [node name]); + return; + } + + NSAssert1 (arg, @"no arg in %@\n", label); + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + + NSTextField *txt = [[NSTextField alloc] initWithFrame:rect]; + + // make the default size be around 30 columns; a typical value for + // these text fields is "xscreensaver-text --cols 40". + // + [txt setStringValue:@"123456789 123456789 123456789 "]; + [txt sizeToFit]; + [[txt cell] setWraps:NO]; + [[txt cell] setScrollable:YES]; + [txt setStringValue:@""]; + + if (label) { + NSTextField *lab = make_label (label); + place_child (parent, lab, NO); + [lab release]; + } + + place_child (parent, txt, (label ? YES : NO)); + + bind_switch_to_preferences (prefs, txt, arg, opts); + [txt release]; +} + + +/* Creates the NSTextField described by the given XML node, + and hooks it up to a Choose button and a file selector widget. +*/ +static void +make_file_selector (NSUserDefaultsController *prefs, + const XrmOptionDescRec *opts, + NSView *parent, NSXMLNode *node, + BOOL dirs_only_p, + BOOL no_label_p) +{ + NSMutableDictionary *dict = + [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"", @"id", + @"", @"_label", + @"", @"arg", + nil]; + parse_attrs (dict, node); + NSString *label = [dict objectForKey:@"_label"]; + NSString *arg = [dict objectForKey:@"arg"]; + + if (!label && !no_label_p) { + NSAssert1 (0, @"no _label in %@\n", [node name]); + return; + } + + NSAssert1 (arg, @"no arg in %@\n", label); + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + + NSTextField *txt = [[NSTextField alloc] initWithFrame:rect]; + + // make the default size be around 20 columns. + // + [txt setStringValue:@"123456789 123456789 "]; + [txt sizeToFit]; + [txt setSelectable:YES]; + [txt setEditable:NO]; + [txt setBezeled:NO]; + [txt setDrawsBackground:NO]; + [[txt cell] setWraps:NO]; + [[txt cell] setScrollable:YES]; + [[txt cell] setLineBreakMode:NSLineBreakByTruncatingHead]; + [txt setStringValue:@""]; + + NSTextField *lab = 0; + if (label) { + lab = make_label (label); + place_child (parent, lab, NO); + [lab release]; + } + + place_child (parent, txt, (label ? YES : NO)); + + bind_switch_to_preferences (prefs, txt, arg, opts); + [txt release]; + + // Make the text field be the same height as the label. + if (lab) { + rect = [txt frame]; + rect.size.height = [lab frame].size.height; + [txt setFrame:rect]; + } + + // Now put a "Choose" button next to it. + // + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + NSButton *choose = [[NSButton alloc] initWithFrame:rect]; + [choose setTitle:@"Choose..."]; + [choose setBezelStyle:NSRoundedBezelStyle]; + [choose sizeToFit]; + + place_child (parent, choose, YES); + + // center the Choose button around the midpoint of the text field. + rect = [choose frame]; + rect.origin.y = ([txt frame].origin.y + + (([txt frame].size.height - rect.size.height) / 2)); + [choose setFrameOrigin:rect.origin]; + + [choose setTarget:[parent window]]; + if (dirs_only_p) + [choose setAction:@selector(chooseClickedDirs:)]; + else + [choose setAction:@selector(chooseClicked:)]; + + [choose release]; +} + + +/* Runs a modal file selector and sets the text field's value to the + selected file or directory. + */ +static void +do_file_selector (NSTextField *txt, BOOL dirs_p) +{ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setAllowsMultipleSelection:NO]; + [panel setCanChooseFiles:!dirs_p]; + [panel setCanChooseDirectories:dirs_p]; + + NSString *file = [txt stringValue]; + if ([file length] <= 0) { + file = NSHomeDirectory(); + if (dirs_p) + file = [file stringByAppendingPathComponent:@"Pictures"]; + } + +// NSString *dir = [file stringByDeletingLastPathComponent]; + + int result = [panel runModalForDirectory:file //dir + file:nil //[file lastPathComponent] + types:nil]; + if (result == NSOKButton) { + NSArray *files = [panel filenames]; + NSString *file = ([files count] > 0 ? [files objectAtIndex:0] : @""); + file = [file stringByAbbreviatingWithTildeInPath]; + [txt setStringValue:file]; + + // Fuck me! Just setting the value of the NSTextField does not cause + // that to end up in the preferences! + // + NSDictionary *dict = [txt infoForBinding:@"value"]; + NSUserDefaultsController *prefs = [dict objectForKey:@"NSObservedObject"]; + NSString *path = [dict objectForKey:@"NSObservedKeyPath"]; + if ([path hasPrefix:@"values."]) // WTF. + path = [path substringFromIndex:7]; + [[prefs values] setValue:file forKey:path]; + +#if 0 + // make sure the end of the string is visible. + NSText *fe = [[txt window] fieldEditor:YES forObject:txt]; + NSRange range; + range.location = [file length]-3; + range.length = 1; + if (! [[txt window] makeFirstResponder:[txt window]]) + [[txt window] endEditingFor:nil]; +// [[txt window] makeFirstResponder:nil]; + [fe setSelectedRange:range]; +// [tv scrollRangeToVisible:range]; +// [txt setNeedsDisplay:YES]; +// [[txt cell] setNeedsDisplay:YES]; +// [txt selectAll:txt]; +#endif + } +} + +/* Returns the NSTextField that is to the left of or above the NSButton. + */ +static NSTextField * +find_text_field_of_button (NSButton *button) +{ + NSView *parent = [button superview]; + NSArray *kids = [parent subviews]; + int nkids = [kids count]; + int i; + NSTextField *f = 0; + for (i = 0; i < nkids; i++) { + NSObject *kid = [kids objectAtIndex:i]; + if ([kid isKindOfClass:[NSTextField class]]) { + f = (NSTextField *) kid; + } else if (kid == button) { + if (! f) abort(); + return f; + } + } + abort(); +} + + +- (void) chooseClicked:(NSObject *)arg +{ + NSButton *choose = (NSButton *) arg; + NSTextField *txt = find_text_field_of_button (choose); + do_file_selector (txt, NO); +} + +- (void) chooseClickedDirs:(NSObject *)arg +{ + NSButton *choose = (NSButton *) arg; + NSTextField *txt = find_text_field_of_button (choose); + do_file_selector (txt, YES); +} + + +/* Creates the number selection control described by the given XML node. + If "type=slider", it's an NSSlider. + If "type=spinbutton", it's a text field with up/down arrows next to it. +*/ +static void +make_number_selector (NSUserDefaultsController *prefs, + const XrmOptionDescRec *opts, + NSView *parent, NSXMLNode *node) +{ + NSMutableDictionary *dict = + [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"", @"id", + @"", @"_label", + @"", @"_low-label", + @"", @"_high-label", + @"", @"type", + @"", @"arg", + @"", @"low", + @"", @"high", + @"", @"default", + @"", @"convert", + nil]; + parse_attrs (dict, node); + NSString *label = [dict objectForKey:@"_label"]; + NSString *low_label = [dict objectForKey:@"_low-label"]; + NSString *high_label = [dict objectForKey:@"_high-label"]; + NSString *type = [dict objectForKey:@"type"]; + NSString *arg = [dict objectForKey:@"arg"]; + NSString *low = [dict objectForKey:@"low"]; + NSString *high = [dict objectForKey:@"high"]; + NSString *def = [dict objectForKey:@"default"]; + NSString *cvt = [dict objectForKey:@"convert"]; + + NSAssert1 (arg, @"no arg in %@\n", label); + NSAssert1 (type, @"no type in %@\n", label); + + if (! low) { + NSAssert1 (0, @"no low in %@\n", [node name]); + return; + } + if (! high) { + NSAssert1 (0, @"no high in %@\n", [node name]); + return; + } + if (! def) { + NSAssert1 (0, @"no default in %@\n", [node name]); + return; + } + if (cvt && ![cvt isEqualToString:@"invert"]) { + NSAssert1 (0, @"if provided, \"convert\" must be \"invert\" in %@", + label); + } + + if ([type isEqualToString:@"slider"]) { + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = 150; + rect.size.height = 20; + NSSlider *slider; + if (cvt) + slider = [[InvertedSlider alloc] initWithFrame:rect]; + else + slider = [[NSSlider alloc] initWithFrame:rect]; + + [slider setMaxValue:[high doubleValue]]; + [slider setMinValue:[low doubleValue]]; + + if (label) { + NSTextField *lab = make_label (label); + place_child (parent, lab, NO); + [lab release]; + } + + if (low_label) { + NSTextField *lab = make_label (low_label); + [lab setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + [lab setAlignment:1]; // right aligned + rect = [lab frame]; + if (rect.size.width < LEFT_LABEL_WIDTH) + rect.size.width = LEFT_LABEL_WIDTH; // make all left labels same size + rect.size.height = [slider frame].size.height; + [lab setFrame:rect]; + place_child (parent, lab, NO); + [lab release]; + } + + place_child (parent, slider, (low_label ? YES : NO)); + + if (! low_label) { + rect = [slider frame]; + if (rect.origin.x < LEFT_LABEL_WIDTH) + rect.origin.x = LEFT_LABEL_WIDTH; // make unlabelled sliders line up too + [slider setFrame:rect]; + } + + if (high_label) { + NSTextField *lab = make_label (high_label); + [lab setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + rect = [lab frame]; + rect.size.height = [slider frame].size.height; + [lab setFrame:rect]; + place_child (parent, lab, YES); + [lab release]; + } + + bind_switch_to_preferences (prefs, slider, arg, opts); + [slider release]; + + } else if ([type isEqualToString:@"spinbutton"]) { + + if (! label) { + NSAssert1 (0, @"no _label in spinbutton %@\n", [node name]); + return; + } + NSAssert1 (!low_label, + @"low-label not allowed in spinbutton \"%@\"\n", [node name]); + NSAssert1 (!high_label, + @"high-label not allowed in spinbutton \"%@\"\n", [node name]); + NSAssert1 (!cvt, @"convert not allowed in spinbutton \"%@\"\n", + [node name]); + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + + NSTextField *txt = [[NSTextField alloc] initWithFrame:rect]; + [txt setStringValue:@"0000.0"]; + [txt sizeToFit]; + [txt setStringValue:@""]; + + if (label) { + NSTextField *lab = make_label (label); + //[lab setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + [lab setAlignment:1]; // right aligned + rect = [lab frame]; + if (rect.size.width < LEFT_LABEL_WIDTH) + rect.size.width = LEFT_LABEL_WIDTH; // make all left labels same size + rect.size.height = [txt frame].size.height; + [lab setFrame:rect]; + place_child (parent, lab, NO); + [lab release]; + } + + place_child (parent, txt, (label ? YES : NO)); + + if (! label) { + rect = [txt frame]; + if (rect.origin.x < LEFT_LABEL_WIDTH) + rect.origin.x = LEFT_LABEL_WIDTH; // make unlabelled spinbtns line up + [txt setFrame:rect]; + } + + rect.size.width = rect.size.height = 10; + NSStepper *step = [[NSStepper alloc] initWithFrame:rect]; + [step sizeToFit]; + place_child (parent, step, YES); + rect = [step frame]; + rect.size.height = [txt frame].size.height; + rect.origin.x -= COLUMN_SPACING; // this one goes close + [step setFrame:rect]; + + [step setMinValue:[low doubleValue]]; + [step setMaxValue:[high doubleValue]]; + [step setAutorepeat:YES]; + [step setValueWraps:NO]; + + double range = [high doubleValue] - [low doubleValue]; + if (range < 1.0) + [step setIncrement:range / 10.0]; + else if (range >= 500) + [step setIncrement:range / 100.0]; + else + [step setIncrement:1.0]; + + bind_switch_to_preferences (prefs, step, arg, opts); + bind_switch_to_preferences (prefs, txt, arg, opts); + + [step release]; + [txt release]; + + } else { + NSAssert2 (0, @"unknown type \"%@\" in \"%@\"\n", type, label); + } +} + + +static void +set_menu_item_object (NSMenuItem *item, NSObject *obj) +{ + /* If the object associated with this menu item looks like a boolean, + store an NSNumber instead of an NSString, since that's what + will be in the preferences (due to similar logic in PrefsReader). + */ + if ([obj isKindOfClass:[NSString class]]) { + NSString *string = (NSString *) obj; + if (NSOrderedSame == [string caseInsensitiveCompare:@"true"] || + NSOrderedSame == [string caseInsensitiveCompare:@"yes"]) + obj = [NSNumber numberWithBool:YES]; + else if (NSOrderedSame == [string caseInsensitiveCompare:@"false"] || + NSOrderedSame == [string caseInsensitiveCompare:@"no"]) + obj = [NSNumber numberWithBool:NO]; + else + obj = string; + } + + [item setRepresentedObject:obj]; + //NSLog (@"menu item \"%@\" = \"%@\" %@", [item title], obj, [obj class]); +} + + +/* Creates the popup menu described by the given XML node (and its children). +*/ +static void +make_option_menu (NSUserDefaultsController *prefs, + const XrmOptionDescRec *opts, + NSView *parent, NSXMLNode *node) +{ + NSArray *children = [node children]; + int i, count = [children count]; + + if (count <= 0) { + NSAssert1 (0, @"no menu items in \"%@\"\n", [node name]); + return; + } + + // get the "id" attribute off the \n"); @@ -266,6 +245,9 @@ static void sanity_check_parameter (const char *filename, parameter *p); static void sanity_check_text_node (const char *filename, const xmlNodePtr node); +static void sanity_check_menu_options (const char *filename, + const xmlChar *node_name, + parameter *p); /* Allocates and returns a new `parameter' object based on the properties in the given XML node. Returns 0 if there's nothing @@ -295,6 +277,13 @@ make_parameter (const char *filename, xmlNodePtr node) else if (!strcmp (name, "file")) p->type = FILENAME; else if (!strcmp (name, "number")) p->type = SPINBUTTON; else if (!strcmp (name, "select")) p->type = SELECT; + + else if (!strcmp (name, "xscreensaver-text") || /* these are ignored in X11 */ + !strcmp (name, "xscreensaver-image")) /* (they are used in Cocoa) */ + { + free (p); + return 0; + } else if (node->type == XML_TEXT_NODE) { sanity_check_text_node (filename, node); @@ -346,7 +335,6 @@ make_parameter (const char *filename, xmlNodePtr node) p->arg = xmlGetProp (node, (xmlChar *) "arg"); p->arg_set = xmlGetProp (node, (xmlChar *) "arg-set"); p->arg_unset = xmlGetProp (node, (xmlChar *) "arg-unset"); - p->test = xmlGetProp (node, (xmlChar *) "test"); /* Check for missing decimal point */ if (debug_p && @@ -408,27 +396,12 @@ make_select_option (const char *filename, xmlNodePtr node) else { parameter *s = calloc (1, sizeof(*s)); - char *enable, *e; s->type = SELECT_OPTION; s->id = xmlGetProp (node, (xmlChar *) "id"); s->label = xmlGetProp (node, (xmlChar *) "_label"); s->arg_set = xmlGetProp (node, (xmlChar *) "arg-set"); s->arg_unset = xmlGetProp (node, (xmlChar *) "arg-unset"); - s->test = xmlGetProp (node, (xmlChar *) "test"); - enable = (char*)xmlGetProp (node, (xmlChar *) "enable"); - - if (enable) - { - enable = strdup (enable); - e = strtok (enable, ", "); - while (e) - { - s->enable = g_list_append (s->enable, strdup (e)); - e = strtok (0, ", "); - } - free (enable); - } sanity_check_parameter (filename, node->name, s); return s; @@ -568,8 +541,56 @@ sanity_check_parameter (const char *filename, const xmlChar *node_name, CHECK (arg_unset, "arg-unset"); # undef CHECK # undef WARN + + if (p->type == SELECT) + sanity_check_menu_options (filename, node_name, p); +} + + +static void +sanity_check_menu_options (const char *filename, const xmlChar *node_name, + parameter *p) +{ + GList *opts; + int noptions = 0; + int nulls = 0; + char *prefix = 0; + +/* fprintf (stderr, "\n## %s\n", p->id);*/ + for (opts = p->options; opts; opts = opts->next) + { + parameter *s = (parameter *) opts->data; + if (!s->arg_set) nulls++; + noptions++; + + if (s->arg_set) + { + char *a = strdup ((char *) s->arg_set); + char *spc = strchr (a, ' '); + if (spc) *spc = 0; + if (prefix) + { + if (strcmp (a, prefix)) + fprintf (stderr, + "%s: %s: both \"%s\" and \"%s\" used in \n", + blurb(), filename, p->id); } + /* "text" nodes show up for all the non-tag text in the file, including all the newlines between tags. Warn if there is text there that is not whitespace. @@ -1807,6 +1828,7 @@ load_configurator_1 (const char *program, const char *arguments, gboolean verbose_p) { const char *dir = hack_configuration_path; + char *base_program; int L = strlen (dir); char *file; char *s; @@ -1815,13 +1837,17 @@ load_configurator_1 (const char *program, const char *arguments, if (L == 0) return 0; - file = (char *) malloc (L + strlen (program) + 10); + base_program = strrchr(program, '/'); + if (base_program) base_program++; + if (!base_program) base_program = (char *) program; + + file = (char *) malloc (L + strlen (base_program) + 10); data = (conf_data *) calloc (1, sizeof(*data)); strcpy (file, dir); if (file[L-1] != '/') file[L++] = '/'; - strcpy (file+L, program); + strcpy (file+L, base_program); for (s = file+L; *s; s++) if (*s == '/' || *s == ' ') diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c index 61e9aa28..b4ac7c86 100644 --- a/driver/demo-Gtk.c +++ b/driver/demo-Gtk.c @@ -233,11 +233,44 @@ static void schedule_preview (state *, const char *cmd); static void kill_preview_subproc (state *, Bool reset_p); static void schedule_preview_check (state *); + +/* Prototypes of functions used by the Glade-generated code, + to avoid warnings. + */ +void exit_menu_cb (GtkMenuItem *, gpointer user_data); +void about_menu_cb (GtkMenuItem *, gpointer user_data); +void doc_menu_cb (GtkMenuItem *, gpointer user_data); +void file_menu_cb (GtkMenuItem *, gpointer user_data); +void activate_menu_cb (GtkMenuItem *, gpointer user_data); +void lock_menu_cb (GtkMenuItem *, gpointer user_data); +void kill_menu_cb (GtkMenuItem *, gpointer user_data); +void restart_menu_cb (GtkWidget *, gpointer user_data); +void run_this_cb (GtkButton *, gpointer user_data); +void manual_cb (GtkButton *, gpointer user_data); +void run_next_cb (GtkButton *, gpointer user_data); +void run_prev_cb (GtkButton *, gpointer user_data); +void pref_changed_cb (GtkWidget *, gpointer user_data); +gboolean pref_changed_event_cb (GtkWidget *, GdkEvent *, gpointer user_data); +void mode_menu_item_cb (GtkWidget *, gpointer user_data); +void switch_page_cb (GtkNotebook *, GtkNotebookPage *, + gint page_num, gpointer user_data); +void browse_image_dir_cb (GtkButton *, gpointer user_data); +void browse_text_file_cb (GtkButton *, gpointer user_data); +void browse_text_program_cb (GtkButton *, gpointer user_data); +void settings_cb (GtkButton *, gpointer user_data); +void settings_adv_cb (GtkButton *, gpointer user_data); +void settings_std_cb (GtkButton *, gpointer user_data); +void settings_switch_page_cb (GtkNotebook *, GtkNotebookPage *, + gint page_num, gpointer user_data); +void settings_cancel_cb (GtkButton *, gpointer user_data); +void settings_ok_cb (GtkButton *, gpointer user_data); /* Some random utility functions */ +const char *blurb (void); + const char * blurb (void) { @@ -716,9 +749,9 @@ about_menu_cb (GtkMenuItem *menuitem, gpointer user_data) look as good in the plain-old default Latin1 "C" locale.) */ #ifdef HAVE_GTK2 - sprintf(copy, ("Copyright \xC2\xA9 1991-2005 %s"), s); + sprintf(copy, ("Copyright \xC2\xA9 1991-2006 %s"), s); #else /* !HAVE_GTK2 */ - sprintf(copy, ("Copyright \251 1991-2005 %s"), s); + sprintf(copy, ("Copyright \251 1991-2006 %s"), s); #endif /* !HAVE_GTK2 */ sprintf (msg, "%s\n\n%s", copy, desc); @@ -978,6 +1011,7 @@ selected_list_element (state *s) static int demo_write_init_file (state *s, saver_preferences *p) { + Display *dpy = GDK_DISPLAY(); #if 0 /* #### try to figure out why shit keeps getting reordered... */ @@ -985,7 +1019,7 @@ demo_write_init_file (state *s, saver_preferences *p) abort(); #endif - if (!write_init_file (p, s->short_version, False)) + if (!write_init_file (dpy, p, s->short_version, False)) { if (s->debug_p) fprintf (stderr, "%s: wrote %s\n", blurb(), init_file_name()); @@ -1024,6 +1058,7 @@ run_this_cb (GtkButton *button, gpointer user_data) G_MODULE_EXPORT void manual_cb (GtkButton *button, gpointer user_data) { + Display *dpy = GDK_DISPLAY(); state *s = global_state_kludge; /* I hate C so much... */ saver_preferences *p = &s->prefs; GtkWidget *list_widget = name_to_widget (s, "list"); @@ -1045,9 +1080,9 @@ manual_cb (GtkButton *button, gpointer user_data) while (*str && !isspace (*str)) str++; *str = 0; str = strrchr (name2, '/'); - if (str) name = str+1; + if (str) name2 = str+1; - cmd = get_string_resource ("manualCommand", "ManualCommand"); + cmd = get_string_resource (dpy, "manualCommand", "ManualCommand"); if (cmd) { char *cmd2 = (char *) malloc (strlen (cmd) + (strlen (name2) * 4) + 100); @@ -1697,7 +1732,7 @@ pref_changed_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) /* Callback on menu items in the "mode" options menu. */ -void +G_MODULE_EXPORT void mode_menu_item_cb (GtkWidget *widget, gpointer user_data) { state *s = (state *) user_data; @@ -2172,7 +2207,7 @@ browse_text_program_cb (GtkButton *button, gpointer user_data) -G_MODULE_EXPORT void +G_MODULE_EXPORT void settings_cb (GtkButton *button, gpointer user_data) { state *s = global_state_kludge; /* I hate C so much... */ @@ -2360,6 +2395,7 @@ scroll_to_current_hack (state *s) static void populate_hack_list (state *s) { + Display *dpy = GDK_DISPLAY(); #ifdef HAVE_GTK2 saver_preferences *p = &s->prefs; GtkTreeView *list = GTK_TREE_VIEW (name_to_widget (s, "list")); @@ -2420,7 +2456,7 @@ populate_hack_list (state *s) pretty_name = (hack->name ? strdup (hack->name) - : make_hack_name (hack->command)); + : make_hack_name (dpy, hack->command)); if (!available_p) { @@ -3152,6 +3188,7 @@ eschew_gtk_lossage (GtkLabel *label) static void populate_demo_window (state *s, int list_elt) { + Display *dpy = GDK_DISPLAY(); saver_preferences *p = &s->prefs; screenhack *hack; char *pretty_name; @@ -3183,7 +3220,7 @@ populate_demo_window (state *s, int list_elt) pretty_name = (hack ? (hack->name ? strdup (hack->name) - : make_hack_name (hack->command)) + : make_hack_name (dpy, hack->command)) : 0); if (hack) @@ -3264,6 +3301,7 @@ sort_hack_cmp (const void *a, const void *b) static void initialize_sort_map (state *s) { + Display *dpy = GDK_DISPLAY(); saver_preferences *p = &s->prefs; int i, j; @@ -3314,7 +3352,7 @@ initialize_sort_map (state *s) screenhack *hack = p->screenhacks[i]; char *name = (hack->name && *hack->name ? strdup (hack->name) - : make_hack_name (hack->command)); + : make_hack_name (dpy, hack->command)); char *str; for (str = name; *str; str++) *str = tolower(*str); @@ -3348,6 +3386,7 @@ initialize_sort_map (state *s) static int maybe_reload_init_file (state *s) { + Display *dpy = GDK_DISPLAY(); saver_preferences *p = &s->prefs; int status = 0; @@ -3371,7 +3410,7 @@ maybe_reload_init_file (state *s) warning_dialog (s->toplevel_widget, b, False, 100); free (b); - load_init_file (p); + load_init_file (dpy, p); initialize_sort_map (s); list_elt = selected_list_element (s); @@ -3755,9 +3794,13 @@ kill_preview_subproc (state *s, Bool reset_p) perror (buf); } } - else if (s->debug_p) - fprintf (stderr, "%s: killed pid %lu (%s)\n", blurb(), - (unsigned long) s->running_preview_pid, ss); + else { + int endstatus; + waitpid(s->running_preview_pid, &endstatus, 0); + if (s->debug_p) + fprintf (stderr, "%s: killed pid %lu (%s)\n", blurb(), + (unsigned long) s->running_preview_pid, ss); + } free (ss); s->running_preview_pid = 0; @@ -4775,7 +4818,7 @@ main (int argc, char **argv) hack_environment (s); /* must be before initialize_sort_map() */ - load_init_file (p); + load_init_file (dpy, p); initialize_sort_map (s); /* Now that Xt has been initialized, and the resources have been read, @@ -5012,7 +5055,8 @@ main (int argc, char **argv) /* Issue any warnings about the running xscreensaver daemon. */ - the_network_is_not_the_computer (s); + if (! s->debug_p) + the_network_is_not_the_computer (s); /* Run the Gtk event loop, and not the Xt event loop. This means that @@ -5030,17 +5074,18 @@ main (int argc, char **argv) gtk_timeout_add (500, delayed_scroll_kludge, s); -#if 0 +#if 1 /* Load every configurator in turn, to scan them for errors all at once. */ - { - int i; - for (i = 0; i < p->screenhacks_count; i++) - { - screenhack *hack = p->screenhacks[i]; - conf_data *d = load_configurator (hack->command, False); - if (d) free_conf_data (d); - } - } + if (s->debug_p) + { + int i; + for (i = 0; i < p->screenhacks_count; i++) + { + screenhack *hack = p->screenhacks[i]; + conf_data *d = load_configurator (hack->command, s->debug_p); + if (d) free_conf_data (d); + } + } #endif diff --git a/driver/exec.c b/driver/exec.c index c9c95500..0f2aaa21 100644 --- a/driver/exec.c +++ b/driver/exec.c @@ -1,5 +1,5 @@ /* exec.c --- executes a program in *this* pid, without an intervening process. - * xscreensaver, Copyright (c) 1991-2005 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-2006 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 @@ -77,6 +77,7 @@ # define fork vfork #endif /* VMS */ +#include "exec.h" extern const char *blurb (void); diff --git a/driver/exec.h b/driver/exec.h new file mode 100644 index 00000000..318410b8 --- /dev/null +++ b/driver/exec.h @@ -0,0 +1,21 @@ +/* exec.c --- executes a program in *this* pid, without an intervening process. + * xscreensaver, Copyright (c) 1991-2006 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_EXEC_H__ +#define __XSCREENSAVER_EXEC_H__ + +extern void exec_command (const char *shell, const char *command, + int nice_level); + +extern int on_path_p (const char *program); + +#endif /* __XSCREENSAVER_EXEC_H__ */ diff --git a/driver/lock.c b/driver/lock.c index 65162a59..cb3053dd 100644 --- a/driver/lock.c +++ b/driver/lock.c @@ -1,5 +1,5 @@ /* lock.c --- handling the password dialog for locking-mode. - * xscreensaver, Copyright (c) 1993-2005 Jamie Zawinski + * xscreensaver, Copyright (c) 1993-2006 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 @@ -37,13 +37,6 @@ static void hp_lock_reset (saver_info *si, Bool lock_p); #endif /* HAVE_XHPDISABLERESET */ -#ifdef HAVE_VT_LOCKSWITCH -# include -# include -# include - static void linux_lock_vt_switch (saver_info *si, Bool lock_p); -#endif /* HAVE_VT_LOCKSWITCH */ - #ifdef HAVE_XF86VMODE # include static void xfree_lock_mode_switch (saver_info *si, Bool lock_p); @@ -59,6 +52,11 @@ ERROR! You must not include vroot.h in this file. #endif +#ifdef HAVE_UNAME +# include /* for hostname info */ +#endif /* HAVE_UNAME */ +#include + #ifndef VMS # include #else /* VMS */ @@ -109,6 +107,9 @@ struct passwd_dialog_data { char *user_string; char *passwd_string; char *login_label; + char *uname_label; + + Bool show_uname_p; XFontStruct *heading_font; XFontStruct *body_font; @@ -116,6 +117,7 @@ struct passwd_dialog_data { XFontStruct *passwd_font; XFontStruct *date_font; XFontStruct *button_font; + XFontStruct *uname_font; Pixel foreground; Pixel background; @@ -144,6 +146,7 @@ struct passwd_dialog_data { Dimension thermo_field_height; Pixmap logo_pixmap; + Pixmap logo_clipmask; int logo_npixels; unsigned long *logo_pixels; @@ -195,20 +198,21 @@ make_passwd_window (saver_info *si) pw->ratio = 1.0; - pw->show_stars_p = get_boolean_resource("passwd.asterisks", "Boolean"); + pw->show_stars_p = get_boolean_resource(si->dpy, "passwd.asterisks", + "Boolean"); - pw->heading_label = get_string_resource ("passwd.heading.label", + pw->heading_label = get_string_resource (si->dpy, "passwd.heading.label", "Dialog.Label.Label"); - pw->body_label = get_string_resource ("passwd.body.label", + pw->body_label = get_string_resource (si->dpy, "passwd.body.label", "Dialog.Label.Label"); - pw->user_label = get_string_resource ("passwd.user.label", + pw->user_label = get_string_resource (si->dpy, "passwd.user.label", "Dialog.Label.Label"); - pw->passwd_label = get_string_resource ("passwd.passwd.label", + pw->passwd_label = get_string_resource (si->dpy, "passwd.passwd.label", "Dialog.Label.Label"); - pw->login_label = get_string_resource ("passwd.login.label", + pw->login_label = get_string_resource (si->dpy, "passwd.login.label", "Dialog.Button.Label"); - pw->date_label = get_string_resource ("dateFormat", "DateFormat"); + pw->date_label = get_string_resource (si->dpy, "dateFormat", "DateFormat"); if (!pw->heading_label) pw->heading_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY"); @@ -227,45 +231,75 @@ make_passwd_window (saver_info *si) pw->heading_label = s; } + /* Get hostname info */ + pw->uname_label = strdup(""); /* Initialy, write nothing */ + +# ifdef HAVE_UNAME + { + struct utsname uts; + + if (uname (&uts) == 0) + { +#if 0 /* Get the full hostname */ + { + char *s; + if ((s = strchr(uts.nodename, '.'))) + *s = 0; + } +#endif + char *s = strdup (uts.nodename); + free (pw->uname_label); + pw->uname_label = s; + } + } +# endif + pw->user_string = strdup (p && p->pw_name ? p->pw_name : "???"); pw->passwd_string = strdup(""); - f = get_string_resource ("passwd.headingFont", "Dialog.Font"); + f = get_string_resource (si->dpy, "passwd.headingFont", "Dialog.Font"); pw->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!pw->heading_font) pw->heading_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource ("passwd.buttonFont", "Dialog.Font"); + f = get_string_resource (si->dpy, "passwd.buttonFont", "Dialog.Font"); pw->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!pw->button_font) pw->button_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource("passwd.bodyFont", "Dialog.Font"); + f = get_string_resource(si->dpy, "passwd.bodyFont", "Dialog.Font"); pw->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!pw->body_font) pw->body_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource("passwd.labelFont", "Dialog.Font"); + f = get_string_resource(si->dpy, "passwd.labelFont", "Dialog.Font"); pw->label_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!pw->label_font) pw->label_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource("passwd.passwdFont", "Dialog.Font"); + f = get_string_resource(si->dpy, "passwd.passwdFont", "Dialog.Font"); pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource("passwd.dateFont", "Dialog.Font"); + f = get_string_resource(si->dpy, "passwd.dateFont", "Dialog.Font"); pw->date_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!pw->date_font) pw->date_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - pw->foreground = get_pixel_resource ("passwd.foreground", - "Dialog.Foreground", - si->dpy, cmap); - pw->background = get_pixel_resource ("passwd.background", - "Dialog.Background", - si->dpy, cmap); + f = get_string_resource(si->dpy, "passwd.unameFont", "Dialog.Font"); + pw->uname_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); + if (!pw->uname_font) pw->uname_font = XLoadQueryFont (si->dpy, "fixed"); + if (f) free (f); + + pw->show_uname_p = get_boolean_resource(si->dpy, "passwd.uname", "Boolean"); + + pw->foreground = get_pixel_resource (si->dpy, cmap, + "passwd.foreground", + "Dialog.Foreground" ); + pw->background = get_pixel_resource (si->dpy, cmap, + "passwd.background", + "Dialog.Background" ); if (pw->foreground == pw->background) { @@ -274,40 +308,40 @@ make_passwd_window (saver_info *si) pw->background = WhitePixelOfScreen (screen); } - pw->passwd_foreground = get_pixel_resource ("passwd.text.foreground", - "Dialog.Text.Foreground", - si->dpy, cmap); - pw->passwd_background = get_pixel_resource ("passwd.text.background", - "Dialog.Text.Background", - si->dpy, cmap); - pw->button_foreground = get_pixel_resource ("splash.Button.foreground", - "Dialog.Button.Foreground", - si->dpy, cmap); - pw->button_background = get_pixel_resource ("splash.Button.background", - "Dialog.Button.Background", - si->dpy, cmap); - pw->thermo_foreground = get_pixel_resource ("passwd.thermometer.foreground", - "Dialog.Thermometer.Foreground", - si->dpy, cmap); - pw->thermo_background = get_pixel_resource ("passwd.thermometer.background", - "Dialog.Thermometer.Background", - si->dpy, cmap); - pw->shadow_top = get_pixel_resource ("passwd.topShadowColor", - "Dialog.Foreground", - si->dpy, cmap); - pw->shadow_bottom = get_pixel_resource ("passwd.bottomShadowColor", - "Dialog.Background", - si->dpy, cmap); - - pw->logo_width = get_integer_resource ("passwd.logo.width", + pw->passwd_foreground = get_pixel_resource (si->dpy, cmap, + "passwd.text.foreground", + "Dialog.Text.Foreground" ); + pw->passwd_background = get_pixel_resource (si->dpy, cmap, + "passwd.text.background", + "Dialog.Text.Background" ); + pw->button_foreground = get_pixel_resource (si->dpy, cmap, + "splash.Button.foreground", + "Dialog.Button.Foreground" ); + pw->button_background = get_pixel_resource (si->dpy, cmap, + "splash.Button.background", + "Dialog.Button.Background" ); + pw->thermo_foreground = get_pixel_resource (si->dpy, cmap, + "passwd.thermometer.foreground", + "Dialog.Thermometer.Foreground" ); + pw->thermo_background = get_pixel_resource ( si->dpy, cmap, + "passwd.thermometer.background", + "Dialog.Thermometer.Background" ); + pw->shadow_top = get_pixel_resource ( si->dpy, cmap, + "passwd.topShadowColor", + "Dialog.Foreground" ); + pw->shadow_bottom = get_pixel_resource (si->dpy, cmap, + "passwd.bottomShadowColor", + "Dialog.Background" ); + + pw->logo_width = get_integer_resource (si->dpy, "passwd.logo.width", "Dialog.Logo.Width"); - pw->logo_height = get_integer_resource ("passwd.logo.height", + pw->logo_height = get_integer_resource (si->dpy, "passwd.logo.height", "Dialog.Logo.Height"); - pw->thermo_width = get_integer_resource ("passwd.thermometer.width", + pw->thermo_width = get_integer_resource (si->dpy, "passwd.thermometer.width", "Dialog.Thermometer.Width"); - pw->internal_border = get_integer_resource ("passwd.internalBorderWidth", + pw->internal_border = get_integer_resource (si->dpy, "passwd.internalBorderWidth", "Dialog.InternalBorderWidth"); - pw->shadow_width = get_integer_resource ("passwd.shadowThickness", + pw->shadow_width = get_integer_resource (si->dpy, "passwd.shadowThickness", "Dialog.ShadowThickness"); if (pw->logo_width == 0) pw->logo_width = 150; @@ -330,6 +364,16 @@ make_passwd_window (saver_info *si) if (overall.width > pw->width) pw->width = overall.width; pw->height += ascent + descent; + /* Measure the uname_label. */ + if ((strlen(pw->uname_label)) && pw->show_uname_p) + { + XTextExtents (pw->uname_font, + pw->uname_label, strlen(pw->uname_label), + &direction, &ascent, &descent, &overall); + if (overall.width > pw->width) pw->width = overall.width; + pw->height += ascent + descent; + } + /* Measure the body_label. */ XTextExtents (pw->body_font, pw->body_label, strlen(pw->body_label), @@ -470,7 +514,7 @@ make_passwd_window (saver_info *si) if (pw->y < y) pw->y = y; } - pw->border_width = get_integer_resource ("passwd.borderWidth", + pw->border_width = get_integer_resource (si->dpy, "passwd.borderWidth", "Dialog.BorderWidth"); si->passwd_dialog = @@ -490,7 +534,7 @@ make_passwd_window (saver_info *si) si->passwd_dialog, cmap, pw->background, &pw->logo_pixels, &pw->logo_npixels, - 0, True); + &pw->logo_clipmask, True); /* Before mapping the window, save the bits that are underneath the rectangle the window will occlude. When we lower the window, we @@ -553,6 +597,9 @@ draw_passwd_window (saver_info *si) (pw->shadow_width * 4)))) + pw->date_font->ascent + pw->date_font->descent); + if ((strlen(pw->uname_label)) && pw->show_uname_p) + height += (pw->uname_font->ascent + pw->uname_font->descent); /* for uname */ + if (pw->login_button_p) height += ((pw->button_font->ascent + pw->button_font->descent) * 2 + 2 * pw->shadow_width); @@ -580,7 +627,19 @@ draw_passwd_window (saver_info *si) XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, pw->heading_label, strlen(pw->heading_label)); - /* text below top heading + /* uname below top heading + */ + if ((strlen(pw->uname_label)) && pw->show_uname_p) + { + XSetFont (si->dpy, gc1, pw->uname_font->fid); + y1 += spacing + pw->uname_font->ascent + pw->uname_font->descent; + sw = string_width (pw->uname_font, pw->uname_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, + pw->uname_label, strlen(pw->uname_label)); + } + + /* text below uname */ XSetFont (si->dpy, gc1, pw->body_font->fid); y1 += spacing + pw->body_font->ascent + pw->body_font->descent; @@ -735,6 +794,8 @@ draw_passwd_window (saver_info *si) XGetGeometry (si->dpy, pw->logo_pixmap, &root, &x, &y, &w, &h, &bw, &d); XSetForeground (si->dpy, gc1, pw->foreground); XSetBackground (si->dpy, gc1, pw->background); + XSetClipMask (si->dpy, gc1, pw->logo_clipmask); + XSetClipOrigin (si->dpy, gc1, x1 + ((x2 - (int)w) / 2), y1 + ((y2 - (int)h) / 2)); if (d == 1) XCopyPlane (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1, 0, 0, w, h, @@ -995,6 +1056,7 @@ destroy_passwd_window (saver_info *si) if (pw->login_label) free (pw->login_label); if (pw->user_string) free (pw->user_string); if (pw->passwd_string) free (pw->passwd_string); + if (pw->uname_label) free (pw->uname_label); if (pw->heading_font) XFreeFont (si->dpy, pw->heading_font); if (pw->body_font) XFreeFont (si->dpy, pw->body_font); @@ -1002,6 +1064,7 @@ destroy_passwd_window (saver_info *si) if (pw->passwd_font) XFreeFont (si->dpy, pw->passwd_font); if (pw->date_font) XFreeFont (si->dpy, pw->date_font); if (pw->button_font) XFreeFont (si->dpy, pw->button_font); + if (pw->uname_font) XFreeFont (si->dpy, pw->uname_font); if (pw->foreground != black && pw->foreground != white) XFreeColors (si->dpy, cmap, &pw->foreground, 1, 0L); @@ -1026,6 +1089,8 @@ destroy_passwd_window (saver_info *si) if (pw->logo_pixmap) XFreePixmap (si->dpy, pw->logo_pixmap); + if (pw-> logo_clipmask) + XFreePixmap (si->dpy, pw->logo_clipmask); if (pw->logo_pixels) { if (pw->logo_npixels) @@ -1132,67 +1197,6 @@ xfree_lock_grab_smasher (saver_info *si, Bool lock_p) #endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ - - -/* This function enables and disables the C-Sh-F1 ... F12 hot-keys, - which, on Linux systems, switches to another virtual console. - We'd like the whole screen/keyboard to be locked, not just one - virtual console, so this function disables that while the X - screen is locked. - - Unfortunately, this doesn't work -- this ioctl only works when - called by root, and we have disavowed our privileges long ago. - */ -#ifdef HAVE_VT_LOCKSWITCH -static void -linux_lock_vt_switch (saver_info *si, Bool lock_p) -{ - saver_preferences *p = &si->prefs; - static Bool vt_locked_p = False; - const char *dev_console = "/dev/console"; - int fd; - - if (lock_p == vt_locked_p) - return; - - if (lock_p && !p->lock_vt_p) - return; - - fd = open (dev_console, O_RDWR); - if (fd < 0) - { - char buf [255]; - sprintf (buf, "%s: couldn't %s VTs: %s", blurb(), - (lock_p ? "lock" : "unlock"), - dev_console); -#if 1 /* #### doesn't work yet, so don't bother complaining */ - perror (buf); -#endif - return; - } - - if (ioctl (fd, (lock_p ? VT_LOCKSWITCH : VT_UNLOCKSWITCH)) == 0) - { - vt_locked_p = lock_p; - - if (p->verbose_p) - fprintf (stderr, "%s: %s VTs\n", blurb(), - (lock_p ? "locked" : "unlocked")); - } - else - { - char buf [255]; - sprintf (buf, "%s: couldn't %s VTs: ioctl", blurb(), - (lock_p ? "lock" : "unlock")); -#if 0 /* #### doesn't work yet, so don't bother complaining */ - perror (buf); -#endif - } - - close (fd); -} -#endif /* HAVE_VT_LOCKSWITCH */ - /* This function enables and disables the C-Alt-Plus and C-Alt-Minus hot-keys, which normally change the resolution of the X server. @@ -1649,9 +1653,6 @@ set_locked_p (saver_info *si, Bool locked_p) #ifdef HAVE_XHPDISABLERESET hp_lock_reset (si, locked_p); /* turn off/on C-Sh-Reset */ #endif -#ifdef HAVE_VT_LOCKSWITCH - linux_lock_vt_switch (si, locked_p); /* turn off/on C-Alt-F1 */ -#endif #ifdef HAVE_XF86VMODE xfree_lock_mode_switch (si, locked_p); /* turn off/on C-Alt-Plus */ #endif diff --git a/driver/passwd-pam.c b/driver/passwd-pam.c index 2452bbc6..5c4f74f2 100644 --- a/driver/passwd-pam.c +++ b/driver/passwd-pam.c @@ -89,6 +89,8 @@ struct pam_closure { Bool verbose_p; }; +Bool pam_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +Bool pam_priv_init (int argc, char **argv, Bool verbose_p); #ifdef HAVE_PAM_FAIL_DELAY /* We handle delays ourself.*/ diff --git a/driver/passwd-pwent.c b/driver/passwd-pwent.c index a2d5e0c8..e5ed51d9 100644 --- a/driver/passwd-pwent.c +++ b/driver/passwd-pwent.c @@ -104,6 +104,11 @@ static char *encrypted_user_passwd = 0; # define ROOT "root" #endif +#ifndef VMS +Bool pwent_priv_init (int argc, char **argv, Bool verbose_p); +Bool pwent_lock_init (int argc, char **argv, Bool verbose_p); +Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +#endif #ifndef VMS diff --git a/driver/passwd.c b/driver/passwd.c index d5a358c5..f651e972 100644 --- a/driver/passwd.c +++ b/driver/passwd.c @@ -63,6 +63,9 @@ extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p); extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p); extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +Bool lock_priv_init (int argc, char **argv, Bool verbose_p); +Bool lock_init (int argc, char **argv, Bool verbose_p); +Bool passwd_valid_p (const char *typed_passwd, Bool verbose_p); /* The authorization methods to try, in order. Note that the last one (the pwent version) is actually two auth methods, diff --git a/driver/prefs.c b/driver/prefs.c index 1ef9a276..c8e4ae14 100644 --- a/driver/prefs.c +++ b/driver/prefs.c @@ -1,5 +1,5 @@ /* dotfile.c --- management of the ~/.xscreensaver file. - * xscreensaver, Copyright (c) 1998-2005 Jamie Zawinski + * xscreensaver, Copyright (c) 1998-2006 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 @@ -26,6 +26,7 @@ #include #include #include +#include /* for PATH_MAX */ #include #include @@ -66,6 +67,11 @@ #include "prefs.h" #include "resources.h" +/* don't use realpath() on fedora system */ +#ifdef _FORTIFY_SOURCE +#undef HAVE_REALPATH +#endif + extern char *progname; extern char *progclass; @@ -73,9 +79,9 @@ extern const char *blurb (void); -static void get_screenhacks (saver_preferences *p); +static void get_screenhacks (Display *, saver_preferences *); static char *format_command (const char *cmd, Bool wrap_p); -static void merge_system_screenhacks (saver_preferences *p, +static void merge_system_screenhacks (Display *, saver_preferences *, screenhack **system_list, int count); static void stop_the_insanity (saver_preferences *p); @@ -97,8 +103,8 @@ chase_symlinks (const char *file) if (realpath (file, buf)) return strdup (buf); - sprintf (buf, "%.100s: realpath %.200s", blurb(), file); - perror(buf); +/* sprintf (buf, "%.100s: realpath %.200s", blurb(), file); + perror(buf);*/ } # endif /* HAVE_REALPATH */ return 0; @@ -203,9 +209,9 @@ init_file_tmp_name (void) } static int -get_byte_resource (char *name, char *class) +get_byte_resource (Display *dpy, char *name, char *class) { - char *s = get_string_resource (name, class); + char *s = get_string_resource (dpy, name, class); char *s2 = s; int n = 0; if (!s) return 0; @@ -632,7 +638,8 @@ write_entry (FILE *out, const char *key, const char *value) } int -write_init_file (saver_preferences *p, const char *version_string, +write_init_file (Display *dpy, + saver_preferences *p, const char *version_string, Bool verbose_p) { int status = -1; @@ -700,10 +707,10 @@ write_init_file (saver_preferences *p, const char *version_string, } /* Kludge, since these aren't in the saver_preferences struct... */ - visual_name = get_string_resource ("visualID", "VisualID"); + visual_name = get_string_resource (dpy, "visualID", "VisualID"); programs = 0; - overlay_stderr_p = get_boolean_resource ("overlayStderr", "Boolean"); - stderr_font = get_string_resource ("font", "Font"); + overlay_stderr_p = get_boolean_resource (dpy, "overlayStderr", "Boolean"); + stderr_font = get_string_resource (dpy, "font", "Font"); i = 0; { @@ -713,7 +720,7 @@ write_init_file (saver_preferences *p, const char *version_string, for (j = 0; j < p->screenhacks_count; j++) { - hack_strings[j] = format_hack (p->screenhacks[j], True); + hack_strings[j] = format_hack (dpy, p->screenhacks[j], True); i += strlen (hack_strings[j]); i += 2; } @@ -771,11 +778,7 @@ write_init_file (saver_preferences *p, const char *version_string, CHECK("timeout") type = pref_time, t = p->timeout; CHECK("cycle") type = pref_time, t = p->cycle; CHECK("lock") type = pref_bool, b = p->lock_p; -# if 0 /* #### not ready yet */ - CHECK("lockVTs") type = pref_bool, b = p->lock_vt_p; -# else - CHECK("lockVTs") continue; /* don't save */ -# endif + CHECK("lockVTs") continue; /* don't save, unused */ CHECK("lockTimeout") type = pref_time, t = p->lock_timeout; CHECK("passwdTimeout") type = pref_time, t = p->passwd_timeout; CHECK("visualID") type = pref_str, s = visual_name; @@ -784,7 +787,11 @@ write_init_file (saver_preferences *p, const char *version_string, CHECK("timestamp") type = pref_bool, b = p->timestamp_p; CHECK("splash") type = pref_bool, b = p->splash_p; CHECK("splashDuration") type = pref_time, t = p->splash_duration; +# ifdef QUAD_MODE CHECK("quad") type = pref_bool, b = p->quad_p; +# else /* !QUAD_MODE */ + CHECK("quad") continue; /* don't save */ +# endif /* !QUAD_MODE */ CHECK("demoCommand") type = pref_str, s = p->demo_command; CHECK("prefsCommand") type = pref_str, s = p->prefs_command; /* CHECK("helpURL") type = pref_str, s = p->help_url; */ @@ -1001,7 +1008,7 @@ free_screenhack_list (screenhack **list, int count) and so on. */ void -load_init_file (saver_preferences *p) +load_init_file (Display *dpy, saver_preferences *p) { static Bool first_time = True; @@ -1016,7 +1023,7 @@ load_init_file (saver_preferences *p) Then clear it out so that it will be parsed again later, after the init file has been read. */ - get_screenhacks (p); + get_screenhacks (dpy, p); system_default_screenhacks = p->screenhacks; system_default_screenhack_count = p->screenhacks_count; p->screenhacks = 0; @@ -1028,63 +1035,69 @@ load_init_file (saver_preferences *p) first_time = False; - p->xsync_p = get_boolean_resource ("synchronous", "Synchronous"); - p->verbose_p = get_boolean_resource ("verbose", "Boolean"); - p->timestamp_p = get_boolean_resource ("timestamp", "Boolean"); - p->lock_p = get_boolean_resource ("lock", "Boolean"); - p->lock_vt_p = get_boolean_resource ("lockVTs", "Boolean"); - p->fade_p = get_boolean_resource ("fade", "Boolean"); - p->unfade_p = get_boolean_resource ("unfade", "Boolean"); - p->fade_seconds = 1000 * get_seconds_resource ("fadeSeconds", "Time"); - p->fade_ticks = get_integer_resource ("fadeTicks", "Integer"); - p->install_cmap_p = get_boolean_resource ("installColormap", "Boolean"); - p->nice_inferior = get_integer_resource ("nice", "Nice"); - p->inferior_memory_limit = get_byte_resource ("memoryLimit", "MemoryLimit"); - p->splash_p = get_boolean_resource ("splash", "Boolean"); - p->quad_p = get_boolean_resource ("quad", "Boolean"); - p->capture_stderr_p = get_boolean_resource ("captureStderr", "Boolean"); - p->ignore_uninstalled_p = get_boolean_resource ("ignoreUninstalledPrograms", + p->xsync_p = get_boolean_resource (dpy, "synchronous", "Synchronous"); + p->verbose_p = get_boolean_resource (dpy, "verbose", "Boolean"); + p->timestamp_p = get_boolean_resource (dpy, "timestamp", "Boolean"); + p->lock_p = get_boolean_resource (dpy, "lock", "Boolean"); + p->fade_p = get_boolean_resource (dpy, "fade", "Boolean"); + p->unfade_p = get_boolean_resource (dpy, "unfade", "Boolean"); + p->fade_seconds = 1000 * get_seconds_resource (dpy, "fadeSeconds", "Time"); + p->fade_ticks = get_integer_resource (dpy, "fadeTicks", "Integer"); + p->install_cmap_p = get_boolean_resource (dpy, "installColormap", "Boolean"); + p->nice_inferior = get_integer_resource (dpy, "nice", "Nice"); + p->inferior_memory_limit = get_byte_resource (dpy, "memoryLimit", + "MemoryLimit"); + p->splash_p = get_boolean_resource (dpy, "splash", "Boolean"); +# ifdef QUAD_MODE + p->quad_p = get_boolean_resource (dpy, "quad", "Boolean"); +# endif + p->capture_stderr_p = get_boolean_resource (dpy, "captureStderr", "Boolean"); + p->ignore_uninstalled_p = get_boolean_resource (dpy, + "ignoreUninstalledPrograms", "Boolean"); - p->initial_delay = 1000 * get_seconds_resource ("initialDelay", "Time"); - p->splash_duration = 1000 * get_seconds_resource ("splashDuration", "Time"); - p->timeout = 1000 * get_minutes_resource ("timeout", "Time"); - p->lock_timeout = 1000 * get_minutes_resource ("lockTimeout", "Time"); - p->cycle = 1000 * get_minutes_resource ("cycle", "Time"); - p->passwd_timeout = 1000 * get_seconds_resource ("passwdTimeout", "Time"); - p->pointer_timeout = 1000 * get_seconds_resource ("pointerPollTime", "Time"); - p->pointer_hysteresis = get_integer_resource ("pointerHysteresis","Integer"); - p->notice_events_timeout = 1000*get_seconds_resource("windowCreationTimeout", + p->initial_delay = 1000 * get_seconds_resource (dpy, "initialDelay", "Time"); + p->splash_duration = 1000 * get_seconds_resource (dpy, "splashDuration", "Time"); + p->timeout = 1000 * get_minutes_resource (dpy, "timeout", "Time"); + p->lock_timeout = 1000 * get_minutes_resource (dpy, "lockTimeout", "Time"); + p->cycle = 1000 * get_minutes_resource (dpy, "cycle", "Time"); + p->passwd_timeout = 1000 * get_seconds_resource (dpy, "passwdTimeout", "Time"); + p->pointer_timeout = 1000 * get_seconds_resource (dpy, "pointerPollTime", "Time"); + p->pointer_hysteresis = get_integer_resource (dpy, "pointerHysteresis","Integer"); + p->notice_events_timeout = 1000*get_seconds_resource(dpy, + "windowCreationTimeout", "Time"); - p->dpms_enabled_p = get_boolean_resource ("dpmsEnabled", "Boolean"); - p->dpms_standby = 1000 * get_minutes_resource ("dpmsStandby", "Time"); - p->dpms_suspend = 1000 * get_minutes_resource ("dpmsSuspend", "Time"); - p->dpms_off = 1000 * get_minutes_resource ("dpmsOff", "Time"); + p->dpms_enabled_p = get_boolean_resource (dpy, "dpmsEnabled", "Boolean"); + p->dpms_standby = 1000 * get_minutes_resource (dpy, "dpmsStandby", "Time"); + p->dpms_suspend = 1000 * get_minutes_resource (dpy, "dpmsSuspend", "Time"); + p->dpms_off = 1000 * get_minutes_resource (dpy, "dpmsOff", "Time"); - p->grab_desktop_p = get_boolean_resource ("grabDesktopImages", "Boolean"); - p->grab_video_p = get_boolean_resource ("grabVideoFrames", "Boolean"); - p->random_image_p = get_boolean_resource ("chooseRandomImages", "Boolean"); - p->image_directory = get_string_resource ("imageDirectory", + p->grab_desktop_p = get_boolean_resource (dpy, "grabDesktopImages", "Boolean"); + p->grab_video_p = get_boolean_resource (dpy, "grabVideoFrames", "Boolean"); + p->random_image_p = get_boolean_resource (dpy, "chooseRandomImages", "Boolean"); + p->image_directory = get_string_resource (dpy, + "imageDirectory", "ImageDirectory"); - p->text_literal = get_string_resource ("textLiteral", "TextLiteral"); - p->text_file = get_string_resource ("textFile", "TextFile"); - p->text_program = get_string_resource ("textProgram", "TextProgram"); - p->text_url = get_string_resource ("textURL", "TextURL"); + p->text_literal = get_string_resource (dpy, "textLiteral", "TextLiteral"); + p->text_file = get_string_resource (dpy, "textFile", "TextFile"); + p->text_program = get_string_resource (dpy, "textProgram", "TextProgram"); + p->text_url = get_string_resource (dpy, "textURL", "TextURL"); - p->shell = get_string_resource ("bourneShell", "BourneShell"); + p->shell = get_string_resource (dpy, "bourneShell", "BourneShell"); - p->demo_command = get_string_resource("demoCommand", "URL"); - p->prefs_command = get_string_resource("prefsCommand", "URL"); - p->help_url = get_string_resource("helpURL", "URL"); - p->load_url_command = get_string_resource("loadURL", "LoadURL"); - p->new_login_command = get_string_resource("newLoginCommand", + p->demo_command = get_string_resource(dpy, "demoCommand", "URL"); + p->prefs_command = get_string_resource(dpy, "prefsCommand", "URL"); + p->help_url = get_string_resource(dpy, "helpURL", "URL"); + p->load_url_command = get_string_resource(dpy, "loadURL", "LoadURL"); + p->new_login_command = get_string_resource(dpy, + "newLoginCommand", "NewLoginCommand"); /* If "*splash" is unset, default to true. */ { - char *s = get_string_resource ("splash", "Boolean"); + char *s = get_string_resource (dpy, "splash", "Boolean"); if (s) free (s); else @@ -1093,40 +1106,43 @@ load_init_file (saver_preferences *p) /* If "*grabDesktopImages" is unset, default to true. */ { - char *s = get_string_resource ("grabDesktopImages", "Boolean"); + char *s = get_string_resource (dpy, "grabDesktopImages", "Boolean"); if (s) free (s); else p->grab_desktop_p = True; } - p->use_xidle_extension = get_boolean_resource ("xidleExtension","Boolean"); + p->use_xidle_extension = get_boolean_resource (dpy, "xidleExtension","Boolean"); #if 0 /* ignore this, it is evil. */ - p->use_mit_saver_extension = get_boolean_resource ("mitSaverExtension", + p->use_mit_saver_extension = get_boolean_resource (dpy, + "mitSaverExtension", "Boolean"); #endif - p->use_sgi_saver_extension = get_boolean_resource ("sgiSaverExtension", + p->use_sgi_saver_extension = get_boolean_resource (dpy, + "sgiSaverExtension", "Boolean"); - p->use_proc_interrupts = get_boolean_resource ("procInterrupts", "Boolean"); + p->use_proc_interrupts = get_boolean_resource (dpy, + "procInterrupts", "Boolean"); p->getviewport_full_of_lies_p = - get_boolean_resource ("GetViewPortIsFullOfLies", "Boolean"); + get_boolean_resource (dpy, "GetViewPortIsFullOfLies", "Boolean"); - get_screenhacks (p); /* Parse the "programs" resource. */ + get_screenhacks (dpy, p); /* Parse the "programs" resource. */ { - char *s = get_string_resource ("selected", "Integer"); + char *s = get_string_resource (dpy, "selected", "Integer"); if (!s || !*s) p->selected_hack = -1; else - p->selected_hack = get_integer_resource ("selected", "Integer"); + p->selected_hack = get_integer_resource (dpy, "selected", "Integer"); if (s) free (s); if (p->selected_hack < 0 || p->selected_hack >= p->screenhacks_count) p->selected_hack = -1; } { - char *s = get_string_resource ("mode", "Mode"); + char *s = get_string_resource (dpy, "mode", "Mode"); if (s && !strcasecmp (s, "one")) p->mode = ONE_HACK; else if (s && !strcasecmp (s, "blank")) p->mode = BLANK_ONLY; else if (s && !strcasecmp (s, "off")) p->mode = DONT_BLANK; @@ -1136,7 +1152,7 @@ load_init_file (saver_preferences *p) } { - char *s = get_string_resource ("textMode", "TextMode"); + char *s = get_string_resource (dpy, "textMode", "TextMode"); if (s && !strcasecmp (s, "url")) p->tmode = TEXT_URL; else if (s && !strcasecmp (s, "literal")) p->tmode = TEXT_LITERAL; else if (s && !strcasecmp (s, "file")) p->tmode = TEXT_FILE; @@ -1147,7 +1163,7 @@ load_init_file (saver_preferences *p) if (system_default_screenhack_count) /* note: first_time is also true */ { - merge_system_screenhacks (p, system_default_screenhacks, + merge_system_screenhacks (dpy, p, system_default_screenhacks, system_default_screenhack_count); free_screenhack_list (system_default_screenhacks, system_default_screenhack_count); @@ -1174,7 +1190,7 @@ load_init_file (saver_preferences *p) This does *not* actually save the file. */ static void -merge_system_screenhacks (saver_preferences *p, +merge_system_screenhacks (Display *dpy, saver_preferences *p, screenhack **system_list, int system_count) { /* Yeah yeah, this is an N^2 operation, but I don't have hashtables handy, @@ -1191,11 +1207,12 @@ merge_system_screenhacks (saver_preferences *p, { char *name; if (!system_list[i]->name) - system_list[i]->name = make_hack_name (system_list[i]->command); + system_list[i]->name = make_hack_name (dpy, + system_list[i]->command); name = p->screenhacks[j]->name; if (!name) - name = make_hack_name (p->screenhacks[j]->command); + name = make_hack_name (dpy, p->screenhacks[j]->command); matched_p = !strcasecmp (name, system_list[i]->name); @@ -1237,7 +1254,7 @@ merge_system_screenhacks (saver_preferences *p, #if 0 fprintf (stderr, "%s: noticed new hack: %s\n", blurb(), - (nh->name ? nh->name : make_hack_name (nh->command))); + (nh->name ? nh->name : make_hack_name (dpy, nh->command))); #endif } } @@ -1348,7 +1365,7 @@ format_command (const char *cmd, Bool wrap_p) by looking for "hacks.XYZ.name", where XYZ is the program.) */ char * -make_hack_name (const char *shell_command) +make_hack_name (Display *dpy, const char *shell_command) { char *s = strdup (shell_command); char *s2; @@ -1373,7 +1390,7 @@ make_hack_name (const char *shell_command) s[50] = 0; sprintf (res_name, "hacks.%s.name", s); /* resource? */ - s2 = get_string_resource (res_name, res_name); + s2 = get_string_resource (dpy, res_name, res_name); if (s2) { free (s); @@ -1397,14 +1414,14 @@ make_hack_name (const char *shell_command) char * -format_hack (screenhack *hack, Bool wrap_p) +format_hack (Display *dpy, screenhack *hack, Bool wrap_p) { int tab = 32; int size; char *h2, *out, *s; int col = 0; - char *def_name = make_hack_name (hack->command); + char *def_name = make_hack_name (dpy, hack->command); /* Don't ever write out a name for a hack if it's the same as the default. */ @@ -1475,7 +1492,7 @@ format_hack (screenhack *hack, Bool wrap_p) static void -get_screenhacks (saver_preferences *p) +get_screenhacks (Display *dpy, saver_preferences *p) { int i, j; int start = 0; @@ -1483,10 +1500,10 @@ get_screenhacks (saver_preferences *p) int size; char *d; - d = get_string_resource ("monoPrograms", "MonoPrograms"); + d = get_string_resource (dpy, "monoPrograms", "MonoPrograms"); if (d && !*d) { free(d); d = 0; } if (!d) - d = get_string_resource ("colorPrograms", "ColorPrograms"); + d = get_string_resource (dpy, "colorPrograms", "ColorPrograms"); if (d && !*d) { free(d); d = 0; } if (d) @@ -1497,7 +1514,7 @@ get_screenhacks (saver_preferences *p) free(d); } - d = get_string_resource ("programs", "Programs"); + d = get_string_resource (dpy, "programs", "Programs"); free_screenhack_list (p->screenhacks, p->screenhacks_count); p->screenhacks = 0; @@ -1593,6 +1610,13 @@ stop_the_insanity (saver_preferences *p) p->dpms_standby > p->dpms_suspend) p->dpms_standby = p->dpms_suspend; + /* These fixes above ignores the case + suspend = 0 and standby > off ... + */ + if (p->dpms_off != 0 && + p->dpms_standby > p->dpms_off) + p->dpms_standby = p->dpms_off; + if (p->dpms_standby == 0 && /* if *all* are 0, then DPMS is disabled */ p->dpms_suspend == 0 && diff --git a/driver/prefs.h b/driver/prefs.h index a4186eb3..c0c047ba 100644 --- a/driver/prefs.h +++ b/driver/prefs.h @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1993-2005 Jamie Zawinski +/* xscreensaver, Copyright (c) 1993-2006 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 @@ -53,7 +53,6 @@ struct saver_preferences { Bool xsync_p; /* whether XSynchronize has been called */ Bool lock_p; /* whether to lock as well as save */ - Bool lock_vt_p; /* whether to lock VTs too, if possible */ Bool fade_p; /* whether to fade to black, if possible */ Bool unfade_p; /* whether to fade from black, if possible */ @@ -64,7 +63,9 @@ struct saver_preferences { Bool install_cmap_p; /* whether we should use our own colormap when using the screen's default visual. */ +# ifdef QUAD_MODE Bool quad_p; /* whether to run four savers per monitor */ +# endif /* QUAD_MODE */ screenhack **screenhacks; /* the programs to run */ int screenhacks_count; @@ -119,19 +120,20 @@ struct saver_preferences { }; -extern void load_init_file (saver_preferences *p); -extern Bool init_file_changed_p (saver_preferences *p); -extern int write_init_file (saver_preferences *p, const char *version_string, +extern void load_init_file (Display *, saver_preferences *); +extern Bool init_file_changed_p (saver_preferences *); +extern int write_init_file (Display *, + saver_preferences *, const char *version_string, Bool verbose_p); const char *init_file_name (void); extern screenhack *parse_screenhack (const char *line); -extern void free_screenhack (screenhack *hack); -extern char *format_hack (screenhack *hack, Bool wrap_p); -char *make_hack_name (const char *shell_command); +extern void free_screenhack (screenhack *); +extern char *format_hack (Display *, screenhack *, Bool wrap_p); +char *make_hack_name (Display *, const char *shell_command); /* From dpms.c */ -extern void sync_server_dpms_settings (Display *dpy, Bool enabled_p, +extern void sync_server_dpms_settings (Display *, Bool enabled_p, int standby_secs, int suspend_secs, int off_secs, Bool verbose_p); diff --git a/driver/remote.c b/driver/remote.c index 6039324f..507da6b7 100644 --- a/driver/remote.c +++ b/driver/remote.c @@ -322,7 +322,7 @@ send_xscreensaver_command (Display *dpy, Atom command, long arg, abort(); else if (arg != 0 && command == XA_DEMO) { - arg1 = 300; /* version number of the XA_DEMO protocol, */ + arg1 = 5000; /* version number of the XA_DEMO protocol, */ arg2 = arg; /* since it didn't use to take an argument. */ } diff --git a/driver/splash.c b/driver/splash.c index d1cc4de0..52c21ad6 100644 --- a/driver/splash.c +++ b/driver/splash.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1991-2005 Jamie Zawinski +/* xscreensaver, Copyright (c) 1991-2006 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 @@ -147,6 +147,7 @@ struct splash_dialog_data { Dimension help_button_x, help_button_y; Pixmap logo_pixmap; + Pixmap logo_clipmask; int logo_npixels; unsigned long *logo_pixels; @@ -177,19 +178,25 @@ make_splash_dialog (saver_info *si) sp = (splash_dialog_data *) calloc (1, sizeof(*sp)); sp->prompt_screen = ssi; - sp->heading_label = get_string_resource ("splash.heading.label", + sp->heading_label = get_string_resource (si->dpy, + "splash.heading.label", "Dialog.Label.Label"); - sp->body_label = get_string_resource ("splash.body.label", + sp->body_label = get_string_resource (si->dpy, + "splash.body.label", "Dialog.Label.Label"); - sp->body2_label = get_string_resource ("splash.body2.label", + sp->body2_label = get_string_resource (si->dpy, + "splash.body2.label", "Dialog.Label.Label"); - sp->demo_label = get_string_resource ("splash.demo.label", + sp->demo_label = get_string_resource (si->dpy, + "splash.demo.label", "Dialog.Button.Label"); #ifdef PREFS_BUTTON - sp->prefs_label = get_string_resource ("splash.prefs.label", + sp->prefs_label = get_string_resource (si->dpy, + "splash.prefs.label", "Dialog.Button.Label"); #endif /* PREFS_BUTTON */ - sp->help_label = get_string_resource ("splash.help.label", + sp->help_label = get_string_resource (si->dpy, + "splash.help.label", "Dialog.Button.Label"); if (!sp->heading_label) @@ -212,27 +219,27 @@ make_splash_dialog (saver_info *si) sp->heading_label = s; } - f = get_string_resource ("splash.headingFont", "Dialog.Font"); + f = get_string_resource (si->dpy, "splash.headingFont", "Dialog.Font"); sp->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!sp->heading_font) sp->heading_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource("splash.bodyFont", "Dialog.Font"); + f = get_string_resource(si->dpy, "splash.bodyFont", "Dialog.Font"); sp->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!sp->body_font) sp->body_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - f = get_string_resource("splash.buttonFont", "Dialog.Font"); + f = get_string_resource(si->dpy, "splash.buttonFont", "Dialog.Font"); sp->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed")); if (!sp->button_font) sp->button_font = XLoadQueryFont (si->dpy, "fixed"); if (f) free (f); - sp->foreground = get_pixel_resource ("splash.foreground", - "Dialog.Foreground", - si->dpy, cmap); - sp->background = get_pixel_resource ("splash.background", - "Dialog.Background", - si->dpy, cmap); + sp->foreground = get_pixel_resource (si->dpy, cmap, + "splash.foreground", + "Dialog.Foreground"); + sp->background = get_pixel_resource (si->dpy, cmap, + "splash.background", + "Dialog.Background"); if (sp->foreground == sp->background) { @@ -241,26 +248,30 @@ make_splash_dialog (saver_info *si) sp->background = WhitePixelOfScreen (ssi->screen); } - sp->button_foreground = get_pixel_resource ("splash.Button.foreground", - "Dialog.Button.Foreground", - si->dpy, cmap); - sp->button_background = get_pixel_resource ("splash.Button.background", - "Dialog.Button.Background", - si->dpy, cmap); - sp->shadow_top = get_pixel_resource ("splash.topShadowColor", - "Dialog.Foreground", - si->dpy, cmap); - sp->shadow_bottom = get_pixel_resource ("splash.bottomShadowColor", - "Dialog.Background", - si->dpy, cmap); - - sp->logo_width = get_integer_resource ("splash.logo.width", + sp->button_foreground = get_pixel_resource (si->dpy, cmap, + "splash.Button.foreground", + "Dialog.Button.Foreground"); + sp->button_background = get_pixel_resource (si->dpy, cmap, + "splash.Button.background", + "Dialog.Button.Background"); + sp->shadow_top = get_pixel_resource (si->dpy, cmap, + "splash.topShadowColor", + "Dialog.Foreground"); + sp->shadow_bottom = get_pixel_resource (si->dpy, cmap, + "splash.bottomShadowColor", + "Dialog.Background"); + + sp->logo_width = get_integer_resource (si->dpy, + "splash.logo.width", "Dialog.Logo.Width"); - sp->logo_height = get_integer_resource ("splash.logo.height", + sp->logo_height = get_integer_resource (si->dpy, + "splash.logo.height", "Dialog.Logo.Height"); - sp->internal_border = get_integer_resource ("splash.internalBorderWidth", + sp->internal_border = get_integer_resource (si->dpy, + "splash.internalBorderWidth", "Dialog.InternalBorderWidth"); - sp->shadow_width = get_integer_resource ("splash.shadowThickness", + sp->shadow_width = get_integer_resource (si->dpy, + "splash.shadowThickness", "Dialog.ShadowThickness"); if (sp->logo_width == 0) sp->logo_width = 150; @@ -393,7 +404,9 @@ make_splash_dialog (saver_info *si) if (y < sy) y = sy; } - bw = get_integer_resource ("splash.borderWidth", "Dialog.BorderWidth"); + bw = get_integer_resource (si->dpy, + "splash.borderWidth", + "Dialog.BorderWidth"); si->splash_dialog = XCreateWindow (si->dpy, @@ -408,7 +421,7 @@ make_splash_dialog (saver_info *si) si->splash_dialog, cmap, sp->background, &sp->logo_pixels, &sp->logo_npixels, - 0, True); + &sp->logo_clipmask, True); XMapRaised (si->dpy, si->splash_dialog); XSync (si->dpy, False); @@ -555,6 +568,8 @@ draw_splash_window (saver_info *si) XGetGeometry (si->dpy, sp->logo_pixmap, &root, &x, &y, &w, &h, &bw, &d); XSetForeground (si->dpy, gc1, sp->foreground); XSetBackground (si->dpy, gc1, sp->background); + XSetClipMask (si->dpy, gc1, sp->logo_clipmask); + XSetClipOrigin (si->dpy, gc1, x1 + ((x2 - (int)w) /2), y1 + ((y2 - (int)h) / 2)); if (d == 1) XCopyPlane (si->dpy, sp->logo_pixmap, si->splash_dialog, gc1, 0, 0, w, h, @@ -672,6 +687,8 @@ destroy_splash_window (saver_info *si) if (sp->logo_pixmap) XFreePixmap (si->dpy, sp->logo_pixmap); + if (sp->logo_clipmask) + XFreePixmap (si->dpy, sp->logo_clipmask); if (sp->logo_pixels) { if (sp->logo_npixels) diff --git a/driver/stderr.c b/driver/stderr.c index 8b7ac8b5..6246dd3a 100644 --- a/driver/stderr.c +++ b/driver/stderr.c @@ -1,5 +1,5 @@ /* stderr.c --- capturing stdout/stderr output onto the screensaver window. - * xscreensaver, Copyright (c) 1991-1998, 2001 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-2006 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 @@ -113,7 +113,7 @@ print_stderr_1 (saver_screen_info *ssi, char *string) if (! ssi->stderr_font) { - char *font_name = get_string_resource ("font", "Font"); + char *font_name = get_string_resource (dpy, "font", "Font"); if (!font_name) font_name = strdup ("fixed"); ssi->stderr_font = XLoadQueryFont (dpy, font_name); if (! ssi->stderr_font) ssi->stderr_font = XLoadQueryFont (dpy, "fixed"); @@ -129,7 +129,7 @@ print_stderr_1 (saver_screen_info *ssi, char *string) Colormap cmap = ssi->cmap; if (!ssi->stderr_overlay_window && - get_boolean_resource("overlayStderr", "Boolean")) + get_boolean_resource(dpy, "overlayStderr", "Boolean")) { make_stderr_overlay_window (ssi); if (ssi->stderr_overlay_window) @@ -138,8 +138,8 @@ print_stderr_1 (saver_screen_info *ssi, char *string) cmap = ssi->stderr_cmap; } - fg = get_pixel_resource ("overlayTextForeground","Foreground",dpy,cmap); - bg = get_pixel_resource ("overlayTextBackground","Background",dpy,cmap); + fg = get_pixel_resource (dpy,cmap,"overlayTextForeground","Foreground"); + bg = get_pixel_resource (dpy,cmap,"overlayTextBackground","Background"); gcv.font = ssi->stderr_font->fid; gcv.foreground = fg; gcv.background = bg; @@ -378,7 +378,7 @@ initialize_stderr (saver_info *si) real_stderr = stderr; real_stdout = stdout; - stderr_dialog_p = get_boolean_resource ("captureStderr", "Boolean"); + stderr_dialog_p = get_boolean_resource (si->dpy, "captureStderr", "Boolean"); if (!stderr_dialog_p) return; diff --git a/driver/subprocs.c b/driver/subprocs.c index 64317982..604825cb 100644 --- a/driver/subprocs.c +++ b/driver/subprocs.c @@ -1,5 +1,5 @@ /* subprocs.c --- choosing, spawning, and killing screenhacks. - * xscreensaver, Copyright (c) 1991-2005 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-2006 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 @@ -25,6 +25,7 @@ #endif #include /* sys/resource.h needs this for timeval */ +#include /* for PATH_MAX */ #ifdef HAVE_SYS_WAIT_H # include /* for waitpid() and associated macros */ @@ -65,6 +66,7 @@ extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ #define Widget void* #include "xscreensaver.h" +#include "exec.h" #include "yarandom.h" #include "visual.h" /* for id_to_visual() */ @@ -216,7 +218,10 @@ struct screenhack_job { static struct screenhack_job *jobs = 0; -/* for debugging -- nothing calls this, but it's useful to invoke from gdb. */ +/* for debugging -- nothing calls this, but it's useful to invoke from gdb. + */ +void show_job_list (void); + void show_job_list (void) { diff --git a/driver/test-passwd.c b/driver/test-passwd.c index 4b647639..a42d466b 100644 --- a/driver/test-passwd.c +++ b/driver/test-passwd.c @@ -59,6 +59,7 @@ int move_mouse_grab (saver_info *si, Window to, Cursor c, int ts) { return 0; } int mouse_screen (saver_info *si) { return 0; } void check_for_leaks (const char *where) { } void exec_command (const char *shell, const char *command, int nice) { } +int on_path_p (const char *program) { return 0; } void shutdown_stderr (saver_info *si) { } const char *blurb(void) { return progname; } @@ -143,6 +144,15 @@ main (int argc, char **argv) exit (1); } +#ifdef NO_LOCKING + if (which == PASS || which == TTY) + { + fprintf (stderr, "%s: compiled with NO_LOCKING\n", progname); + exit (1); + } +#endif + +#ifndef NO_LOCKING /* before hack_uid() for proper permissions */ lock_priv_init (argc, argv, True); @@ -153,6 +163,7 @@ main (int argc, char **argv) si->locking_disabled_p = True; si->nolock_reason = "error getting password"; } +#endif progclass = "XScreenSaver"; @@ -178,13 +189,14 @@ main (int argc, char **argv) db = p->db; XtGetApplicationNameAndClass (si->dpy, &progname, &progclass); - load_init_file (&si->prefs); + load_init_file (si->dpy, &si->prefs); } p->verbose_p = True; while (1) { +#ifndef NO_LOCKING if (which == PASS) { if (unlock_p (si)) @@ -195,7 +207,9 @@ main (int argc, char **argv) XSync(si->dpy, False); sleep (3); } - else if (which == SPLASH) + else +#endif + if (which == SPLASH) { XEvent event; make_splash_dialog (si); @@ -224,10 +238,12 @@ main (int argc, char **argv) if (pass[strlen(pass)-1] == '\n') pass[strlen(pass)-1] = 0; +#ifndef NO_LOCKING if (passwd_valid_p (pass, True)) printf ("%s: Ok!\n", progname); else printf ("%s: Wrong!\n", progname); +#endif } else abort(); diff --git a/driver/test-uid.c b/driver/test-uid.c index b4db41dd..6a1f9cc1 100644 --- a/driver/test-uid.c +++ b/driver/test-uid.c @@ -51,7 +51,7 @@ print(void) (p && p->pw_name ? p->pw_name : "???"), (g && g->gr_name ? g->gr_name : "???")); - size = sizeof(groups) / sizeof(gid_t) + size = sizeof(groups) / sizeof(gid_t); n = getgroups(size - 1, groups); if (n < 0) perror("getgroups failed"); diff --git a/driver/windows.c b/driver/windows.c index e6ca0bf5..ff7d6ddc 100644 --- a/driver/windows.c +++ b/driver/windows.c @@ -1,5 +1,5 @@ /* windows.c --- turning the screen black; dealing with visuals, virtual roots. - * xscreensaver, Copyright (c) 1991-2004 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-2006 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 @@ -1419,7 +1419,12 @@ initialize_screensaver_window_1 (saver_screen_info *ssi) attrs.backing_pixel = ssi->black_pixel; attrs.border_pixel = ssi->black_pixel; - if (p->debug_p && !p->quad_p) width = width / 2; + if (p->debug_p +# ifdef QUAD_MODE + && !p->quad_p +# endif + ) + width = width / 2; if (!p->verbose_p || printed_visual_info) ; @@ -1677,7 +1682,12 @@ resize_screensaver_window (saver_info *si) changes.height = height; changes.border_width = 0; - if (p->debug_p && !p->quad_p) changes.width = changes.width / 2; + if (p->debug_p +# ifdef QUAD_MODE + && !p->quad_p +# endif + ) + changes.width = changes.width / 2; if (p->verbose_p) fprintf (stderr, diff --git a/driver/xscreensaver-command.c b/driver/xscreensaver-command.c index a74b0c1b..f068b54c 100644 --- a/driver/xscreensaver-command.c +++ b/driver/xscreensaver-command.c @@ -65,7 +65,7 @@ static char *usage = "\n\ usage: %s - diff --git a/hacks/config/critical.xml b/hacks/config/critical.xml index cb2707e6..18fcf2da 100644 --- a/hacks/config/critical.xml +++ b/hacks/config/critical.xml @@ -13,14 +13,10 @@ low="0" high="20000" default="10000" convert="invert"/> - - - - - <_description> Draws a system of self-organizing lines. It starts out as random squiggles, but after a few iterations, order begins to appear. -Written by Martin Pool. + +Written by Martin Pool; 1999. diff --git a/hacks/config/crystal.xml b/hacks/config/crystal.xml index ac4be6a2..782d48db 100644 --- a/hacks/config/crystal.xml +++ b/hacks/config/crystal.xml @@ -33,6 +33,8 @@ <_description> Moving polygons, similar to a kaleidescope (more like a kaleidescope -than the hack called `kaleid,' actually.) This one by Jouk Jansen. +than the one called `kaleid,' actually). + +Written by Jouk Jansen; 1998. diff --git a/hacks/config/cube21.xml b/hacks/config/cube21.xml index 0e250f67..78ae0d2b 100644 --- a/hacks/config/cube21.xml +++ b/hacks/config/cube21.xml @@ -28,36 +28,34 @@ _label="Delay in ending position" _low-label="Short" _high-label="Long" low="10.0" high="100.0" default="40.0"/> - - - - - - +
+ + + +
+
+ +
<_description> Animates a Rubik-like puzzle known as Cube 21 or Square-1. -The rotations are chosen randomly. Requires OpenGL. +The rotations are chosen randomly. -Written by Vasek Potocek. +Written by Vasek Potocek; 2005. diff --git a/hacks/config/cubenetic.xml b/hacks/config/cubenetic.xml index a3ca352a..ffe465bc 100644 --- a/hacks/config/cubenetic.xml +++ b/hacks/config/cubenetic.xml @@ -16,22 +16,16 @@ - - @@ -46,11 +40,14 @@ _low-label="Low" _high-label="High" low="1" high="20" default="3"/> + + <_description> Draws a pulsating set of overlapping boxes with ever-chaning blobby patterns undulating across their surfaces. It's sort of a cubist Lavalite. -Written by Jamie Zawinski. + +Written by Jamie Zawinski; 2002. diff --git a/hacks/config/cubestorm.xml b/hacks/config/cubestorm.xml index f4cb9b86..67966444 100644 --- a/hacks/config/cubestorm.xml +++ b/hacks/config/cubestorm.xml @@ -30,6 +30,8 @@ <_description> Draws a series of rotating 3D boxes that intersect each other and -eventually fill space. Written by Jamie Zawinski. +eventually fill space. + +Written by Jamie Zawinski; 2003. diff --git a/hacks/config/cynosure.xml b/hacks/config/cynosure.xml index 4206353f..2f018e29 100644 --- a/hacks/config/cynosure.xml +++ b/hacks/config/cynosure.xml @@ -19,9 +19,8 @@ <_description> -A hack similar to `greynetic', but less frenetic. The first -implementation was by Stephen Linhart; then Ozymandias G. Desiderata -wrote a Java applet clone. That clone was discovered by Jamie -Zawinski, and ported to C for inclusion here. +Random dropshadowed rectangles pop onto the screen in lockstep. + +Written by Ozymandias G. Desiderata, Jamie Zawinski, and Stephen Linhart; 1998. diff --git a/hacks/config/dangerball.xml b/hacks/config/dangerball.xml index 2206fd07..db8da5fd 100644 --- a/hacks/config/dangerball.xml +++ b/hacks/config/dangerball.xml @@ -26,6 +26,7 @@ <_description> Draws a ball that periodically extrudes many random spikes. Ouch! -Written by Jamie Zawinski. + +Written by Jamie Zawinski; 2001. diff --git a/hacks/config/decayscreen.xml b/hacks/config/decayscreen.xml index 4faacc4d..c9b3ec27 100644 --- a/hacks/config/decayscreen.xml +++ b/hacks/config/decayscreen.xml @@ -27,11 +27,14 @@