From 94a3509a3d914f3f791e025b0ad474c2601bfa36 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Fri, 30 May 2014 12:16:36 -0400 Subject: [PATCH 1/1] From http://www.jwz.org/xscreensaver/xscreensaver-5.26.tar.gz -rw-r--r-- 1 zblaxell zblaxell 8760550 Dec 9 06:20 xscreensaver-5.26.tar.gz 8055822b661733e68550872a4ae6b6129c0b73fc xscreensaver-5.26.tar.gz --- INSTALL | 183 + Makefile.in | 370 + OSX/Default-568h@2x.png | Bin 0 -> 18594 bytes OSX/English.lproj/InfoPlist.strings | Bin 0 -> 92 bytes .../SaverRunner.nib/designable.nib | 1790 + .../SaverRunner.nib/keyedobjects.nib | Bin 0 -> 13707 bytes OSX/InvertedSlider.h | 38 + OSX/InvertedSlider.m | 151 + OSX/Makefile | 233 + OSX/PrefsReader.h | 56 + OSX/PrefsReader.m | 571 + OSX/README | 40 + OSX/SaverListController.h | 36 + OSX/SaverListController.m | 351 + OSX/SaverRunner.h | 77 + OSX/SaverRunner.icns | Bin 0 -> 62554 bytes OSX/SaverRunner.m | 1244 + OSX/SaverRunner.plist | 38 + OSX/Sparkle.framework/Headers | 1 + OSX/Sparkle.framework/Resources | 1 + OSX/Sparkle.framework/Sparkle | 1 + .../Versions/A/Headers/SUAppcast.h | 36 + .../Versions/A/Headers/SUAppcastItem.h | 60 + .../Versions/A/Headers/SUUpdater.h | 161 + .../A/Headers/SUVersionComparisonProtocol.h | 29 + .../A/Headers/SUVersionDisplayProtocol.h | 27 + .../Versions/A/Headers/Sparkle.h | 21 + .../Versions/A/Resources/Info.plist | 40 + .../Versions/A/Resources/License.txt | 38 + .../A/Resources/SUModelTranslation.plist | 182 + .../Versions/A/Resources/SUStatus.nib | Bin 0 -> 6565 bytes .../ar.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7118 bytes .../A/Resources/ar.lproj/SUPasswordPrompt.nib | Bin 0 -> 5993 bytes .../A/Resources/ar.lproj/SUUpdateAlert.nib | Bin 0 -> 10445 bytes .../ar.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12737 bytes .../A/Resources/ar.lproj/Sparkle.strings | Bin 0 -> 8896 bytes .../cs.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7039 bytes .../A/Resources/cs.lproj/SUUpdateAlert.nib | Bin 0 -> 10241 bytes .../cs.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12782 bytes .../A/Resources/cs.lproj/Sparkle.strings | Bin 0 -> 8642 bytes .../da.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7018 bytes .../A/Resources/da.lproj/SUPasswordPrompt.nib | Bin 0 -> 5942 bytes .../A/Resources/da.lproj/SUUpdateAlert.nib | Bin 0 -> 10347 bytes .../da.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12635 bytes .../A/Resources/da.lproj/Sparkle.strings | Bin 0 -> 8818 bytes .../de.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7109 bytes .../A/Resources/de.lproj/SUUpdateAlert.nib | Bin 0 -> 10386 bytes .../de.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12699 bytes .../A/Resources/de.lproj/Sparkle.strings | Bin 0 -> 9246 bytes .../en.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7015 bytes .../A/Resources/en.lproj/SUPasswordPrompt.nib | Bin 0 -> 5936 bytes .../A/Resources/en.lproj/SUUpdateAlert.nib | Bin 0 -> 10258 bytes .../en.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12566 bytes .../A/Resources/en.lproj/Sparkle.strings | Bin 0 -> 9042 bytes .../es.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7052 bytes .../A/Resources/es.lproj/SUUpdateAlert.nib | Bin 0 -> 10492 bytes .../es.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12872 bytes .../A/Resources/es.lproj/Sparkle.strings | Bin 0 -> 8956 bytes .../Contents/Info.plist | 50 + .../Contents/MacOS/finish_installation | Bin 0 -> 138260 bytes .../finish_installation.app/Contents/PkgInfo | 1 + .../Contents/Resources/SUStatus.nib | Bin 0 -> 6565 bytes .../Contents/Resources/Sparkle.icns | Bin 0 -> 50219 bytes .../Resources/ar.lproj/Sparkle.strings | Bin 0 -> 8896 bytes .../Resources/cs.lproj/Sparkle.strings | Bin 0 -> 8642 bytes .../Resources/da.lproj/Sparkle.strings | Bin 0 -> 8818 bytes .../Resources/de.lproj/Sparkle.strings | Bin 0 -> 9246 bytes .../Resources/en.lproj/Sparkle.strings | Bin 0 -> 9042 bytes .../Resources/es.lproj/Sparkle.strings | Bin 0 -> 8956 bytes .../Resources/fr.lproj/Sparkle.strings | Bin 0 -> 9204 bytes .../Resources/is.lproj/Sparkle.strings | Bin 0 -> 6772 bytes .../Resources/it.lproj/Sparkle.strings | Bin 0 -> 9136 bytes .../Resources/ja.lproj/Sparkle.strings | Bin 0 -> 7518 bytes .../Resources/nl.lproj/Sparkle.strings | Bin 0 -> 9374 bytes .../Resources/pl.lproj/Sparkle.strings | Bin 0 -> 9532 bytes .../Resources/pt_BR.lproj/Sparkle.strings | Bin 0 -> 8330 bytes .../Resources/pt_PT.lproj/Sparkle.strings | Bin 0 -> 8652 bytes .../Resources/ro.lproj/Sparkle.strings | Bin 0 -> 9386 bytes .../Resources/ru.lproj/Sparkle.strings | Bin 0 -> 8662 bytes .../Resources/sl.lproj/Sparkle.strings | Bin 0 -> 8778 bytes .../Resources/sv.lproj/Sparkle.strings | Bin 0 -> 8600 bytes .../Resources/th.lproj/Sparkle.strings | Bin 0 -> 8946 bytes .../Resources/tr.lproj/Sparkle.strings | Bin 0 -> 9284 bytes .../Resources/uk.lproj/Sparkle.strings | Bin 0 -> 8644 bytes .../Resources/zh_CN.lproj/Sparkle.strings | Bin 0 -> 6908 bytes .../Resources/zh_TW.lproj/Sparkle.strings | Bin 0 -> 6642 bytes .../fr.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7076 bytes .../A/Resources/fr.lproj/SUUpdateAlert.nib | Bin 0 -> 10436 bytes .../fr.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12914 bytes .../A/Resources/fr.lproj/Sparkle.strings | Bin 0 -> 9204 bytes .../Versions/A/Resources/fr_CA.lproj | 1 + .../is.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7013 bytes .../A/Resources/is.lproj/SUUpdateAlert.nib | Bin 0 -> 10221 bytes .../is.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12780 bytes .../A/Resources/is.lproj/Sparkle.strings | Bin 0 -> 6772 bytes .../it.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7002 bytes .../A/Resources/it.lproj/SUUpdateAlert.nib | Bin 0 -> 10353 bytes .../it.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12716 bytes .../A/Resources/it.lproj/Sparkle.strings | Bin 0 -> 9136 bytes .../ja.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7103 bytes .../A/Resources/ja.lproj/SUUpdateAlert.nib | Bin 0 -> 10436 bytes .../ja.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12524 bytes .../A/Resources/ja.lproj/Sparkle.strings | Bin 0 -> 7518 bytes .../ko.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 6919 bytes .../A/Resources/ko.lproj/SUUpdateAlert.nib | Bin 0 -> 10079 bytes .../ko.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12417 bytes .../nl.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7007 bytes .../A/Resources/nl.lproj/SUUpdateAlert.nib | Bin 0 -> 10333 bytes .../nl.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12515 bytes .../A/Resources/nl.lproj/Sparkle.strings | Bin 0 -> 9374 bytes .../pl.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7039 bytes .../A/Resources/pl.lproj/SUUpdateAlert.nib | Bin 0 -> 10223 bytes .../pl.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12564 bytes .../A/Resources/pl.lproj/Sparkle.strings | Bin 0 -> 9532 bytes .../Versions/A/Resources/pt.lproj | 1 + .../pt_BR.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7080 bytes .../pt_BR.lproj/SUPasswordPrompt.nib | Bin 0 -> 5967 bytes .../A/Resources/pt_BR.lproj/SUUpdateAlert.nib | Bin 0 -> 10328 bytes .../pt_BR.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12785 bytes .../A/Resources/pt_BR.lproj/Sparkle.strings | Bin 0 -> 8330 bytes .../pt_PT.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7094 bytes .../A/Resources/pt_PT.lproj/SUUpdateAlert.nib | Bin 0 -> 10513 bytes .../pt_PT.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12886 bytes .../A/Resources/pt_PT.lproj/Sparkle.strings | Bin 0 -> 8652 bytes .../ro.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7117 bytes .../A/Resources/ro.lproj/SUUpdateAlert.nib | Bin 0 -> 10466 bytes .../ro.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12592 bytes .../A/Resources/ro.lproj/Sparkle.strings | Bin 0 -> 9386 bytes .../ru.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7143 bytes .../A/Resources/ru.lproj/SUUpdateAlert.nib | Bin 0 -> 10524 bytes .../ru.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12864 bytes .../A/Resources/ru.lproj/Sparkle.strings | Bin 0 -> 8662 bytes .../sk.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7068 bytes .../A/Resources/sk.lproj/SUUpdateAlert.nib | Bin 0 -> 10270 bytes .../sk.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12778 bytes .../sl.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7103 bytes .../A/Resources/sl.lproj/SUUpdateAlert.nib | Bin 0 -> 10232 bytes .../sl.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12751 bytes .../A/Resources/sl.lproj/Sparkle.strings | Bin 0 -> 8778 bytes .../sv.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7022 bytes .../A/Resources/sv.lproj/SUUpdateAlert.nib | Bin 0 -> 10385 bytes .../sv.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12727 bytes .../A/Resources/sv.lproj/Sparkle.strings | Bin 0 -> 8600 bytes .../th.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7087 bytes .../A/Resources/th.lproj/SUPasswordPrompt.nib | Bin 0 -> 5985 bytes .../A/Resources/th.lproj/SUUpdateAlert.nib | Bin 0 -> 10342 bytes .../th.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12658 bytes .../A/Resources/th.lproj/Sparkle.strings | Bin 0 -> 8946 bytes .../tr.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7179 bytes .../A/Resources/tr.lproj/SUUpdateAlert.nib | Bin 0 -> 10477 bytes .../tr.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12731 bytes .../A/Resources/tr.lproj/Sparkle.strings | Bin 0 -> 9284 bytes .../uk.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 7233 bytes .../A/Resources/uk.lproj/SUUpdateAlert.nib | Bin 0 -> 10624 bytes .../uk.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12774 bytes .../A/Resources/uk.lproj/Sparkle.strings | Bin 0 -> 8644 bytes .../zh_CN.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 6938 bytes .../A/Resources/zh_CN.lproj/SUUpdateAlert.nib | Bin 0 -> 10244 bytes .../zh_CN.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12334 bytes .../A/Resources/zh_CN.lproj/Sparkle.strings | Bin 0 -> 6908 bytes .../zh_TW.lproj/SUAutomaticUpdateAlert.nib | Bin 0 -> 6891 bytes .../A/Resources/zh_TW.lproj/SUUpdateAlert.nib | Bin 0 -> 10040 bytes .../zh_TW.lproj/SUUpdatePermissionPrompt.nib | Bin 0 -> 12315 bytes .../A/Resources/zh_TW.lproj/Sparkle.strings | Bin 0 -> 6642 bytes OSX/Sparkle.framework/Versions/A/Sparkle | Bin 0 -> 403600 bytes OSX/Sparkle.framework/Versions/Current | 1 + OSX/Updater.h | 35 + OSX/Updater.m | 140 + OSX/Updater.plist | 50 + OSX/Updater.xib | 344 + OSX/XScreenSaver.icns | Bin 0 -> 77001 bytes OSX/XScreenSaver.plist | 30 + OSX/XScreenSaverConfigSheet.h | 79 + OSX/XScreenSaverConfigSheet.m | 3582 ++ OSX/XScreenSaverDMG.icns | Bin 0 -> 110173 bytes OSX/XScreenSaverFolder.icns | Bin 0 -> 327214 bytes OSX/XScreenSaverGLView.h | 39 + OSX/XScreenSaverGLView.m | 485 + OSX/XScreenSaverPkg.icns | Bin 0 -> 256741 bytes OSX/XScreenSaverSubclass.m | 33 + OSX/XScreenSaverView.h | 130 + OSX/XScreenSaverView.m | 2026 + OSX/XScreenSaverView.m.orig | 1804 + OSX/XScreenSaverWebloc.icns | Bin 0 -> 88285 bytes OSX/apple2-app.xml | 35 + OSX/bindist-DS_Store | Bin 0 -> 15364 bytes OSX/bindist.rtf | 74 + OSX/bindist.webloc | 8 + OSX/build-fntable.pl | 137 + OSX/config.sub | 1793 + OSX/iSaverRunner.ai | 3593 ++ OSX/iSaverRunner.plist | 67 + OSX/iSaverRunner.xib | 176 + OSX/iSaverRunner1024.png | Bin 0 -> 46983 bytes OSX/iSaverRunner114.png | Bin 0 -> 3809 bytes OSX/iSaverRunner29.png | Bin 0 -> 845 bytes OSX/iSaverRunner29t.png | Bin 0 -> 906 bytes OSX/iSaverRunner50.png | Bin 0 -> 1506 bytes OSX/iSaverRunner57.png | Bin 0 -> 1688 bytes OSX/iSaverRunner72.png | Bin 0 -> 2224 bytes OSX/icmp-warning.pl | 49 + OSX/installer.png | Bin 0 -> 26216 bytes OSX/installer.rtf | 27 + OSX/installer.sh | 106 + OSX/installer.xml | 29 + OSX/ios-function-table.m | 423 + OSX/iosgrabimage.m | 125 + OSX/iostextclient.m | 575 + OSX/jwxyz-timers.h | 29 + OSX/jwxyz-timers.m | 408 + OSX/jwxyz.h | 741 + OSX/jwxyz.h.rej | 16 + OSX/jwxyz.m | 3506 ++ OSX/jwxyz.m.orig | 3499 ++ OSX/main.m | 29 + OSX/osxgrabscreen.m | 445 + OSX/phosphor-app.xml | 37 + OSX/sign_update.rb | 7 + OSX/sparkle_dsa_pub.pem | 20 + OSX/update-info-plist.pl | 410 + OSX/update-thumbnail.pl | 165 + OSX/updates.pl | 215 + OSX/updates.xml | 44 + OSX/xscreensaver_Prefix.pch | 33 + README | 1475 + README.VMS | 57 + README.hacking | 180 + aclocal.m4 | 443 + config.guess | 1568 + config.h-vms | 284 + config.h.in | 503 + config.sub | 1788 + configure | 16563 +++++++ configure.in | 4465 ++ driver/.gdbinit | 27 + driver/Makefile.in | 1025 + driver/README | 6 + driver/XScreenSaver-Xm.ad | 126 + driver/XScreenSaver.ad.in | 509 + driver/XScreenSaver_Xm_ad.h | 108 + driver/XScreenSaver_ad.h | 371 + driver/auth.h | 54 + driver/compile_axp.com | 15 + driver/compile_decc.com | 15 + driver/demo-Gtk-conf.c | 1997 + driver/demo-Gtk-conf.h | 31 + driver/demo-Gtk-stubs.h | 90 + driver/demo-Gtk-support.c | 219 + driver/demo-Gtk-support.h | 61 + driver/demo-Gtk-widgets.c | 1764 + driver/demo-Gtk-widgets.h | 6 + driver/demo-Gtk.c | 5355 +++ driver/demo-Xm-widgets.c | 907 + driver/demo-Xm.c | 1875 + driver/dpms.c | 296 + driver/exec.c | 300 + driver/exec.h | 21 + driver/link_axp.com | 15 + driver/link_decc.com | 15 + driver/lock.c | 2268 + driver/mlstring.c | 229 + driver/mlstring.h | 57 + driver/passwd-helper.c | 162 + driver/passwd-kerberos.c | 251 + driver/passwd-pam.c | 514 + driver/passwd-pwent.c | 312 + driver/passwd.c | 334 + driver/pdf2jpeg.m | 152 + driver/pdf2jpeg.man | 43 + driver/prefs.c | 1691 + driver/prefs.h | 36 + driver/remote.c | 595 + driver/remote.h | 24 + driver/screens.c | 1077 + driver/screensaver-properties.desktop.in | 8 + driver/setuid.c | 361 + driver/splash.c | 925 + driver/stderr.c | 560 + driver/subprocs.c | 1375 + driver/test-apm.c | 101 + driver/test-fade.c | 123 + driver/test-grab.c | 89 + driver/test-mlstring.c | 312 + driver/test-passwd.c | 305 + driver/test-randr.c | 339 + driver/test-screens.c | 208 + driver/test-uid.c | 209 + driver/test-vp.c | 213 + driver/test-xdpms.c | 179 + driver/test-xinerama.c | 112 + driver/timers.c | 1676 + driver/types.h | 437 + driver/vms-getpwnam.c | 129 + driver/vms-hpwd.c | 75 + driver/vms-pwd.h | 48 + driver/vms-validate.c | 75 + driver/vms_axp.opt | 5 + driver/vms_axp_12.opt | 5 + driver/vms_decc.opt | 5 + driver/vms_decc_12.opt | 5 + driver/windows.c | 2001 + driver/xdpyinfo.c | 1098 + driver/xscreensaver-command.c | 450 + driver/xscreensaver-command.man | 263 + driver/xscreensaver-demo.glade2 | 3136 ++ driver/xscreensaver-demo.glade2p | 19 + driver/xscreensaver-demo.man | 398 + driver/xscreensaver-getimage-desktop | 174 + driver/xscreensaver-getimage-desktop.man | 55 + driver/xscreensaver-getimage-file | 1058 + driver/xscreensaver-getimage-file.man | 66 + driver/xscreensaver-getimage-video | 141 + driver/xscreensaver-getimage-video.man | 51 + driver/xscreensaver-getimage.c | 1968 + driver/xscreensaver-getimage.man | 73 + driver/xscreensaver-text | 870 + driver/xscreensaver-text.man | 85 + driver/xscreensaver.c | 2429 + driver/xscreensaver.h | 208 + driver/xscreensaver.man | 903 + driver/xscreensaver.pam.in | 13 + driver/xset.c | 389 + hacks/.gdbinit | 12 + hacks/Makefile.in | 2824 ++ hacks/README | 6 + hacks/abstractile.c | 1589 + hacks/abstractile.man | 52 + hacks/analogtv.c | 2209 + hacks/analogtv.h | 312 + hacks/anemone.c | 445 + hacks/anemone.man | 74 + hacks/anemotaxis.c | 753 + hacks/anemotaxis.man | 78 + hacks/ant.c | 1371 + hacks/ant.man | 96 + hacks/apollonian.c | 846 + hacks/apollonian.man | 70 + hacks/apple2-main.c | 1813 + hacks/apple2.c | 860 + hacks/apple2.h | 121 + hacks/apple2.man | 206 + hacks/asm6502.c | 2268 + hacks/asm6502.h | 181 + hacks/attraction.c | 1104 + hacks/attraction.man | 214 + hacks/automata.h | 64 + hacks/barcode.c | 1987 + hacks/barcode.man | 61 + hacks/blaster.c | 1190 + hacks/blaster.man | 65 + hacks/blitspin.c | 434 + hacks/blitspin.man | 96 + hacks/bouboule.c | 865 + hacks/bouboule.man | 80 + hacks/boxfit.c | 559 + hacks/boxfit.man | 102 + hacks/braid.c | 474 + hacks/braid.man | 69 + hacks/bsod.c | 4592 ++ hacks/bsod.man | 140 + hacks/bubbles-default.c | 151 + hacks/bubbles.c | 1433 + hacks/bubbles.h | 224 + hacks/bubbles.man | 140 + hacks/bumps.c | 730 + hacks/bumps.man | 80 + hacks/ccurve.c | 860 + hacks/ccurve.man | 60 + hacks/celtic.c | 1119 + hacks/celtic.man | 64 + hacks/check-configs.pl | 355 + hacks/cloudlife.c | 420 + hacks/cloudlife.man | 87 + hacks/compass.c | 978 + hacks/compass.man | 57 + hacks/compile_axp.com | 148 + hacks/compile_decc.com | 148 + hacks/config/README | 256 + hacks/config/abstractile.xml | 34 + hacks/config/anemone.xml | 59 + hacks/config/anemotaxis.xml | 38 + hacks/config/ant.xml | 72 + hacks/config/antinspect.xml | 23 + hacks/config/antmaze.xml | 21 + hacks/config/antspotlight.xml | 23 + hacks/config/apollonian.xml | 40 + hacks/config/apple2.xml | 63 + hacks/config/atlantis.xml | 48 + hacks/config/attraction.xml | 85 + hacks/config/atunnel.xml | 24 + hacks/config/barcode.xml | 34 + hacks/config/blaster.xml | 61 + hacks/config/blinkbox.xml | 33 + hacks/config/blitspin.xml | 44 + hacks/config/blocktube.xml | 32 + hacks/config/boing.xml | 49 + hacks/config/bouboule.xml | 32 + hacks/config/bouncingcow.xml | 30 + hacks/config/boxed.xml | 56 + hacks/config/boxfit.xml | 63 + hacks/config/braid.xml | 37 + hacks/config/bsod.xml | 100 + hacks/config/bubble3d.xml | 23 + hacks/config/bubbles.xml | 40 + hacks/config/bumps.xml | 34 + hacks/config/cage.xml | 25 + hacks/config/carousel.xml | 55 + hacks/config/ccurve.xml | 30 + hacks/config/celtic.xml | 30 + hacks/config/circuit.xml | 35 + hacks/config/cloudlife.xml | 39 + hacks/config/companioncube.xml | 54 + hacks/config/compass.xml | 22 + hacks/config/coral.xml | 34 + hacks/config/crackberg.xml | 50 + hacks/config/critical.xml | 29 + hacks/config/crystal.xml | 46 + hacks/config/cube21.xml | 75 + hacks/config/cubenetic.xml | 65 + hacks/config/cubestorm.xml | 40 + hacks/config/cubicgrid.xml | 30 + hacks/config/cwaves.xml | 29 + hacks/config/cynosure.xml | 30 + hacks/config/dangerball.xml | 35 + hacks/config/decayscreen.xml | 47 + hacks/config/deco.xml | 43 + hacks/config/deluxe.xml | 37 + hacks/config/demon.xml | 39 + hacks/config/discrete.xml | 30 + hacks/config/distort.xml | 51 + hacks/config/dnalogo.xml | 38 + hacks/config/drift.xml | 29 + hacks/config/endgame.xml | 27 + hacks/config/engine.xml | 42 + hacks/config/epicycle.xml | 54 + hacks/config/eruption.xml | 51 + hacks/config/euler2d.xml | 51 + hacks/config/extrusion.xml | 43 + hacks/config/fadeplot.xml | 33 + hacks/config/fiberlamp.xml | 29 + hacks/config/fireworkx.xml | 28 + hacks/config/flag.xml | 39 + hacks/config/flame.xml | 37 + hacks/config/flipflop.xml | 50 + hacks/config/flipscreen3d.xml | 25 + hacks/config/fliptext.xml | 54 + hacks/config/flow.xml | 58 + hacks/config/fluidballs.xml | 53 + hacks/config/flurry.xml | 30 + hacks/config/flyingtoasters.xml | 40 + hacks/config/fontglide.xml | 52 + hacks/config/forest.xml | 28 + hacks/config/fuzzyflakes.xml | 64 + hacks/config/galaxy.xml | 35 + hacks/config/gears.xml | 38 + hacks/config/geodesic.xml | 59 + hacks/config/gflux.xml | 59 + hacks/config/glblur.xml | 45 + hacks/config/glcells.xml | 62 + hacks/config/gleidescope.xml | 39 + hacks/config/glforestfire.xml | 44 + hacks/config/glhanoi.xml | 52 + hacks/config/glknots.xml | 61 + hacks/config/glmatrix.xml | 52 + hacks/config/glplanet.xml | 40 + hacks/config/glschool.xml | 43 + hacks/config/glslideshow.xml | 53 + hacks/config/glsnake.xml | 55 + hacks/config/gltext.xml | 49 + hacks/config/goop.xml | 63 + hacks/config/grav.xml | 34 + hacks/config/greynetic.xml | 23 + hacks/config/halftone.xml | 57 + hacks/config/halo.xml | 40 + hacks/config/helix.xml | 25 + hacks/config/hexadrop.xml | 58 + hacks/config/hilbert.xml | 75 + hacks/config/hopalong.xml | 62 + hacks/config/hyperball.xml | 64 + hacks/config/hypercube.xml | 75 + hacks/config/hypertorus.xml | 114 + hacks/config/hypnowheel.xml | 52 + hacks/config/ifs.xml | 63 + hacks/config/imsmap.xml | 44 + hacks/config/interaggregate.xml | 31 + hacks/config/interference.xml | 55 + hacks/config/intermomentary.xml | 35 + hacks/config/jigglypuff.xml | 93 + hacks/config/jigsaw.xml | 49 + hacks/config/juggle.xml | 58 + hacks/config/juggler3d.xml | 53 + hacks/config/julia.xml | 37 + hacks/config/kaleidescope.xml | 40 + hacks/config/kaleidocycle.xml | 55 + hacks/config/klein.xml | 128 + hacks/config/kumppa.xml | 30 + hacks/config/lament.xml | 28 + hacks/config/laser.xml | 36 + hacks/config/lavalite.xml | 88 + hacks/config/lcdscrub.xml | 56 + hacks/config/lightning.xml | 28 + hacks/config/lisa.xml | 48 + hacks/config/lissie.xml | 50 + hacks/config/lmorph.xml | 49 + hacks/config/lockward.xml | 65 + hacks/config/loop.xml | 35 + hacks/config/m6502.xml | 51 + hacks/config/maze.xml | 69 + hacks/config/memscroller.xml | 34 + hacks/config/menger.xml | 49 + hacks/config/metaballs.xml | 53 + hacks/config/mirrorblob.xml | 72 + hacks/config/mismunch.xml | 42 + hacks/config/moebius.xml | 27 + hacks/config/moebiusgears.xml | 45 + hacks/config/moire.xml | 36 + hacks/config/moire2.xml | 32 + hacks/config/molecule.xml | 59 + hacks/config/morph3d.xml | 32 + hacks/config/mountain.xml | 29 + hacks/config/munch.xml | 61 + hacks/config/nerverot.xml | 61 + hacks/config/noof.xml | 21 + hacks/config/noseguy.xml | 17 + hacks/config/pacman.xml | 26 + hacks/config/pedal.xml | 31 + hacks/config/penetrate.xml | 32 + hacks/config/penrose.xml | 54 + hacks/config/petri.xml | 81 + hacks/config/phosphor.xml | 48 + hacks/config/photopile.xml | 63 + hacks/config/piecewise.xml | 44 + hacks/config/pinion.xml | 47 + hacks/config/pipes.xml | 47 + hacks/config/polyhedra.xml | 199 + hacks/config/polyominoes.xml | 34 + hacks/config/polytopes.xml | 111 + hacks/config/pong.xml | 46 + hacks/config/popsquares.xml | 54 + hacks/config/providence.xml | 27 + hacks/config/pulsar.xml | 41 + hacks/config/pyro.xml | 35 + hacks/config/qix.xml | 72 + hacks/config/quasicrystal.xml | 53 + hacks/config/queens.xml | 29 + hacks/config/rd-bomb.xml | 65 + hacks/config/rdbomb.xml | 65 + hacks/config/ripples.xml | 53 + hacks/config/rocks.xml | 44 + hacks/config/rorschach.xml | 36 + hacks/config/rotor.xml | 38 + hacks/config/rotzoomer.xml | 39 + hacks/config/rubik.xml | 38 + hacks/config/rubikblocks.xml | 65 + hacks/config/sballs.xml | 35 + hacks/config/shadebobs.xml | 37 + hacks/config/sierpinski.xml | 36 + hacks/config/sierpinski3d.xml | 32 + hacks/config/skytentacles.xml | 69 + hacks/config/slidescreen.xml | 52 + hacks/config/slip.xml | 45 + hacks/config/sonar.xml | 83 + hacks/config/speedmine.xml | 60 + hacks/config/sphere.xml | 28 + hacks/config/spheremonics.xml | 58 + hacks/config/spiral.xml | 36 + hacks/config/spotlight.xml | 32 + hacks/config/sproingies.xml | 34 + hacks/config/squiral.xml | 49 + hacks/config/stairs.xml | 23 + hacks/config/starfish.xml | 41 + hacks/config/starwars.xml | 61 + hacks/config/stonerview.xml | 25 + hacks/config/strange.xml | 32 + hacks/config/substrate.xml | 43 + hacks/config/superquadrics.xml | 34 + hacks/config/surfaces.xml | 73 + hacks/config/swirl.xml | 31 + hacks/config/t3d.xml | 58 + hacks/config/tangram.xml | 43 + hacks/config/thornbird.xml | 35 + hacks/config/timetunnel.xml | 41 + hacks/config/topblock.xml | 62 + hacks/config/triangle.xml | 26 + hacks/config/tronbit.xml | 39 + hacks/config/truchet.xml | 39 + hacks/config/twang.xml | 59 + hacks/config/unknownpleasures.xml | 55 + hacks/config/vermiculate.xml | 20 + hacks/config/vidwhacker.xml | 28 + hacks/config/vines.xml | 28 + hacks/config/voronoi.xml | 61 + hacks/config/wander.xml | 53 + hacks/config/webcollage.xml | 54 + hacks/config/whirlwindwarp.xml | 26 + hacks/config/whirlygig.xml | 88 + hacks/config/worm.xml | 37 + hacks/config/wormhole.xml | 29 + hacks/config/xanalogtv.xml | 41 + hacks/config/xflame.xml | 33 + hacks/config/xjack.xml | 23 + hacks/config/xlyap.xml | 50 + hacks/config/xmatrix.xml | 66 + hacks/config/xrayswarm.xml | 21 + hacks/config/xspirograph.xml | 30 + hacks/config/xss.dtd | 109 + hacks/config/xss.xsd | 375 + hacks/config/zoom.xml | 52 + hacks/coral.c | 307 + hacks/coral.man | 64 + hacks/critical.c | 452 + hacks/critical.man | 94 + hacks/crystal.c | 1289 + hacks/crystal.man | 81 + hacks/cwaves.c | 212 + hacks/cwaves.man | 76 + hacks/cynosure.c | 436 + hacks/cynosure.man | 64 + hacks/decayscreen.c | 383 + hacks/decayscreen.man | 92 + hacks/deco.c | 338 + hacks/deco.man | 105 + hacks/deluxe.c | 463 + hacks/deluxe.man | 72 + hacks/demon.c | 989 + hacks/demon.man | 69 + hacks/discrete.c | 462 + hacks/discrete.man | 61 + hacks/distort.c | 866 + hacks/distort.man | 137 + hacks/drift.c | 702 + hacks/drift.man | 79 + hacks/epicycle.c | 783 + hacks/epicycle.man | 204 + hacks/eruption.c | 520 + hacks/eruption.man | 77 + hacks/euler2d.c | 888 + hacks/euler2d.man | 69 + hacks/euler2d.tex | 337 + hacks/fadeplot.c | 246 + hacks/fadeplot.man | 65 + hacks/fiberlamp.c | 473 + hacks/fiberlamp.man | 65 + hacks/fireworkx.c | 850 + hacks/fireworkx.man | 88 + hacks/flag.c | 568 + hacks/flag.man | 92 + hacks/flame.c | 460 + hacks/flame.man | 74 + hacks/flow.c | 1231 + hacks/flow.man | 137 + hacks/fluidballs.c | 840 + hacks/fluidballs.man | 90 + hacks/fontglide.c | 1688 + hacks/fontglide.man | 124 + hacks/forest.c | 260 + hacks/forest.man | 62 + hacks/fps.c | 251 + hacks/fps.h | 35 + hacks/fpsI.h | 42 + hacks/fuzzyflakes.c | 639 + hacks/fuzzyflakes.man | 112 + hacks/galaxy.c | 469 + hacks/galaxy.man | 87 + hacks/glx/Makefile.in | 2978 ++ hacks/glx/README | 10 + hacks/glx/antinspect.c | 723 + hacks/glx/antinspect.man | 56 + hacks/glx/antmaze.c | 1648 + hacks/glx/antmaze.man | 52 + hacks/glx/ants.h | 45 + hacks/glx/antspotlight.c | 824 + hacks/glx/antspotlight.man | 56 + hacks/glx/atlantis.c | 579 + hacks/glx/atlantis.h | 129 + hacks/glx/atlantis.man | 78 + hacks/glx/atunnel.c | 330 + hacks/glx/atunnel.man | 83 + hacks/glx/b_draw.c | 239 + hacks/glx/b_lockglue.c | 237 + hacks/glx/b_sphere.c | 219 + hacks/glx/blinkbox.c | 597 + hacks/glx/blinkbox.man | 73 + hacks/glx/blocktube.c | 449 + hacks/glx/blocktube.man | 73 + hacks/glx/boing.c | 683 + hacks/glx/boing.man | 105 + hacks/glx/bouncingcow.c | 544 + hacks/glx/bouncingcow.man | 73 + hacks/glx/boxed.c | 1315 + hacks/glx/boxed.h | 4116 ++ hacks/glx/boxed.man | 56 + hacks/glx/bubble3d.c | 281 + hacks/glx/bubble3d.h | 100 + hacks/glx/bubble3d.man | 62 + hacks/glx/buildlwo.c | 96 + hacks/glx/buildlwo.h | 38 + hacks/glx/cage.c | 489 + hacks/glx/cage.man | 61 + hacks/glx/carousel.c | 923 + hacks/glx/carousel.man | 109 + hacks/glx/chessgames.h | 343 + hacks/glx/chessmodels.c | 1733 + hacks/glx/chessmodels.h | 44 + hacks/glx/circuit.c | 2283 + hacks/glx/circuit.man | 72 + hacks/glx/companion.c | 613 + hacks/glx/companion_disc.c | 9593 ++++ hacks/glx/companion_heart.c | 653 + hacks/glx/companion_quad.c | 389 + hacks/glx/companioncube.man | 85 + hacks/glx/cow_face.c | 341 + hacks/glx/cow_hide.c | 13055 ++++++ hacks/glx/cow_hoofs.c | 1037 + hacks/glx/cow_horns.c | 1025 + hacks/glx/cow_tail.c | 464 + hacks/glx/cow_udder.c | 1520 + hacks/glx/crackberg.c | 1463 + hacks/glx/crackberg.man | 123 + hacks/glx/cube21.c | 968 + hacks/glx/cube21.man | 147 + hacks/glx/cubenetic.c | 610 + hacks/glx/cubenetic.man | 89 + hacks/glx/cubestorm.c | 429 + hacks/glx/cubestorm.man | 77 + hacks/glx/cubicgrid.c | 295 + hacks/glx/cubicgrid.man | 83 + hacks/glx/dangerball.c | 388 + hacks/glx/dangerball.man | 72 + hacks/glx/dnalogo.c | 2497 ++ hacks/glx/dnapizza.h | 122 + hacks/glx/dolphin.c | 2061 + hacks/glx/dropshadow.c | 181 + hacks/glx/dropshadow.h | 51 + hacks/glx/dxf2gl.pl | 501 + hacks/glx/e_textures.h | 1478 + hacks/glx/endgame.c | 993 + hacks/glx/endgame.man | 72 + hacks/glx/engine.c | 1022 + hacks/glx/engine.man | 80 + hacks/glx/extrusion-helix2.c | 47 + hacks/glx/extrusion-helix3.c | 46 + hacks/glx/extrusion-helix4.c | 63 + hacks/glx/extrusion-joinoffset.c | 148 + hacks/glx/extrusion-screw.c | 114 + hacks/glx/extrusion-taper.c | 218 + hacks/glx/extrusion-twistoid.c | 213 + hacks/glx/extrusion.c | 560 + hacks/glx/extrusion.h | 55 + hacks/glx/extrusion.man | 71 + hacks/glx/flipflop.c | 874 + hacks/glx/flipflop.man | 95 + hacks/glx/flipscreen3d.c | 545 + hacks/glx/flipscreen3d.man | 61 + hacks/glx/fliptext.c | 1008 + hacks/glx/fliptext.man | 114 + hacks/glx/flurry-smoke.c | 1442 + hacks/glx/flurry-spark.c | 285 + hacks/glx/flurry-star.c | 106 + hacks/glx/flurry-texture.c | 224 + hacks/glx/flurry.c | 567 + hacks/glx/flurry.h | 296 + hacks/glx/flurry.man | 73 + hacks/glx/flyingtoasters.c | 874 + hacks/glx/flyingtoasters.man | 86 + hacks/glx/font-ximage.c | 256 + hacks/glx/font-ximage.h | 30 + hacks/glx/fps-gl.c | 113 + hacks/glx/gears.c | 946 + hacks/glx/gears.man | 79 + hacks/glx/geodesic.c | 831 + hacks/glx/geodesic.man | 79 + hacks/glx/gflux.c | 838 + hacks/glx/gflux.man | 111 + hacks/glx/glblur.c | 640 + hacks/glx/glblur.man | 76 + hacks/glx/glcells.c | 1328 + hacks/glx/glcells.man | 97 + hacks/glx/gleidescope.c | 1630 + hacks/glx/gleidescope.man | 77 + hacks/glx/glforestfire.c | 1147 + hacks/glx/glforestfire.man | 130 + hacks/glx/glhanoi.c | 2065 + hacks/glx/glhanoi.man | 83 + hacks/glx/glknots.c | 463 + hacks/glx/glknots.man | 81 + hacks/glx/gllist.c | 9 + hacks/glx/gllist.h | 28 + hacks/glx/glmatrix.c | 1069 + hacks/glx/glmatrix.man | 116 + hacks/glx/glplanet.c | 662 + hacks/glx/glplanet.man | 70 + hacks/glx/glschool.c | 222 + 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 | 274 + hacks/glx/glschool_gl.h | 47 + hacks/glx/glslideshow.c | 1260 + hacks/glx/glslideshow.man | 131 + hacks/glx/glsnake.c | 2694 ++ hacks/glx/glsnake.man | 98 + hacks/glx/gltext.c | 678 + hacks/glx/gltext.man | 123 + hacks/glx/gltrackball.c | 156 + hacks/glx/gltrackball.h | 59 + hacks/glx/glut_roman.h | 2455 + hacks/glx/glut_stroke.c | 57 + hacks/glx/glut_swidth.c | 73 + hacks/glx/glutstroke.h | 47 + hacks/glx/glxfonts.c | 671 + hacks/glx/glxfonts.h | 58 + hacks/glx/grab-ximage.c | 839 + hacks/glx/grab-ximage.h | 76 + hacks/glx/hilbert.c | 1150 + hacks/glx/hilbert.man | 103 + hacks/glx/hypertorus.c | 1031 + hacks/glx/hypertorus.man | 188 + hacks/glx/hypnowheel.c | 298 + hacks/glx/hypnowheel.man | 80 + hacks/glx/involute.c | 968 + hacks/glx/involute.h | 77 + hacks/glx/jigglypuff.c | 1089 + hacks/glx/jigglypuff.man | 121 + hacks/glx/jigsaw.c | 1534 + hacks/glx/jigsaw.man | 90 + hacks/glx/juggler3d.c | 3097 ++ hacks/glx/juggler3d.man | 183 + hacks/glx/jwzgles.c | 3969 ++ hacks/glx/jwzgles.h | 519 + hacks/glx/jwzglesI.h | 335 + hacks/glx/kaleidocycle.c | 566 + hacks/glx/kaleidocycle.man | 96 + hacks/glx/klein.c | 2044 + hacks/glx/klein.man | 299 + hacks/glx/lament.c | 2062 + hacks/glx/lament.man | 68 + hacks/glx/lavalite.c | 1569 + hacks/glx/lavalite.man | 160 + hacks/glx/lockward.c | 934 + hacks/glx/lockward.man | 79 + hacks/glx/marching.c | 641 + hacks/glx/marching.h | 48 + hacks/glx/menger.c | 555 + hacks/glx/menger.man | 78 + hacks/glx/mirrorblob.c | 1862 + hacks/glx/mirrorblob.man | 107 + hacks/glx/moebius.c | 816 + hacks/glx/moebius.man | 65 + hacks/glx/moebiusgears.c | 414 + hacks/glx/moebiusgears.man | 86 + hacks/glx/molecule.c | 1735 + hacks/glx/molecule.man | 160 + hacks/glx/molecules.sh | 22 + hacks/glx/morph3d.c | 833 + hacks/glx/morph3d.man | 57 + hacks/glx/noof.c | 477 + hacks/glx/noof.man | 52 + hacks/glx/normals.c | 52 + hacks/glx/normals.h | 44 + hacks/glx/photopile.c | 785 + hacks/glx/photopile.man | 113 + hacks/glx/pinion.c | 1534 + hacks/glx/pinion.man | 82 + hacks/glx/pipeobjs.c | 3262 ++ hacks/glx/pipes.c | 1252 + hacks/glx/pipes.man | 85 + hacks/glx/polyhedra-gl.c | 758 + hacks/glx/polyhedra.c | 2458 + hacks/glx/polyhedra.h | 52 + hacks/glx/polyhedra.man | 124 + hacks/glx/polytopes.c | 3213 ++ hacks/glx/polytopes.man | 207 + hacks/glx/providence.c | 820 + hacks/glx/providence.man | 66 + hacks/glx/pulsar.c | 521 + hacks/glx/pulsar.man | 102 + hacks/glx/quasicrystal.c | 445 + hacks/glx/quasicrystal.man | 84 + hacks/glx/queens.c | 657 + hacks/glx/queens.man | 66 + hacks/glx/rotator.c | 247 + hacks/glx/rotator.h | 60 + hacks/glx/rubik.c | 2167 + hacks/glx/rubik.man | 69 + hacks/glx/rubikblocks.c | 662 + hacks/glx/rubikblocks.man | 117 + hacks/glx/s1_1.c | 1733 + hacks/glx/s1_2.c | 1733 + hacks/glx/s1_3.c | 1733 + hacks/glx/s1_4.c | 1733 + hacks/glx/s1_5.c | 1733 + hacks/glx/s1_6.c | 1733 + hacks/glx/s1_b.c | 505 + hacks/glx/sballs.c | 873 + hacks/glx/sballs.man | 125 + hacks/glx/shark.c | 1395 + hacks/glx/sierpinski3d.c | 583 + hacks/glx/sierpinski3d.man | 67 + hacks/glx/skytentacles.c | 1095 + hacks/glx/skytentacles.man | 102 + hacks/glx/sonar-icmp.c | 1417 + hacks/glx/sonar-sim.c | 112 + hacks/glx/sonar.c | 1047 + hacks/glx/sonar.h | 71 + hacks/glx/sonar.man | 169 + hacks/glx/sphere.c | 138 + hacks/glx/sphere.h | 23 + hacks/glx/spheremonics.c | 927 + hacks/glx/spheremonics.man | 92 + hacks/glx/sproingies.c | 928 + hacks/glx/sproingies.h | 25 + hacks/glx/sproingies.man | 68 + hacks/glx/sproingiewrap.c | 252 + hacks/glx/stairs.c | 627 + hacks/glx/stairs.man | 56 + hacks/glx/starwars.c | 1051 + hacks/glx/starwars.h | 312 + hacks/glx/starwars.man | 181 + hacks/glx/starwars.txt | 311 + hacks/glx/stonerview-move.c | 155 + hacks/glx/stonerview-move.h | 32 + hacks/glx/stonerview-osc.c | 341 + hacks/glx/stonerview-osc.h | 175 + hacks/glx/stonerview-view.c | 116 + hacks/glx/stonerview.c | 189 + hacks/glx/stonerview.h | 67 + hacks/glx/stonerview.man | 53 + hacks/glx/superquadrics.c | 797 + hacks/glx/superquadrics.man | 70 + hacks/glx/surfaces.c | 683 + hacks/glx/surfaces.man | 127 + hacks/glx/swim.c | 232 + hacks/glx/tangram.c | 1097 + hacks/glx/tangram.man | 67 + hacks/glx/tangram_shapes.c | 236 + hacks/glx/tangram_shapes.h | 15 + hacks/glx/teapot.c | 282 + hacks/glx/teapot.h | 7 + hacks/glx/teapot2.h | 6330 +++ hacks/glx/texfont.c | 575 + hacks/glx/texfont.h | 37 + hacks/glx/timetunnel.c | 1267 + hacks/glx/timetunnel.man | 105 + hacks/glx/toast.c | 185 + hacks/glx/toast2.c | 209 + hacks/glx/toaster.c | 371 + hacks/glx/toaster_base.c | 125 + hacks/glx/toaster_handle.c | 59 + hacks/glx/toaster_handle2.c | 35 + hacks/glx/toaster_jet.c | 173 + hacks/glx/toaster_knob.c | 71 + hacks/glx/toaster_slots.c | 101 + hacks/glx/toaster_wing.c | 38 + hacks/glx/topblock.c | 890 + hacks/glx/topblock.h | 45 + hacks/glx/topblock.man | 170 + hacks/glx/trackball.c | 331 + hacks/glx/trackball.h | 82 + hacks/glx/tronbit.c | 550 + hacks/glx/tronbit.man | 79 + hacks/glx/tronbit_idle1.c | 247 + hacks/glx/tronbit_idle2.c | 175 + hacks/glx/tronbit_no.c | 1087 + hacks/glx/tronbit_yes.c | 31 + hacks/glx/tube.c | 400 + hacks/glx/tube.h | 32 + hacks/glx/tunnel_draw.c | 512 + hacks/glx/tunnel_draw.h | 11 + hacks/glx/unknownpleasures.c | 512 + hacks/glx/unknownpleasures.man | 74 + hacks/glx/voronoi.c | 506 + hacks/glx/voronoi.man | 88 + hacks/glx/vrml2gl.pl | 361 + hacks/glx/wfront2gl.pl | 361 + hacks/glx/whale.c | 1887 + hacks/glx/xlock-gl-utils.c | 219 + hacks/glx/xpm-ximage.c | 464 + hacks/glx/xpm-ximage.h | 31 + hacks/glx/xscreensaver-gl-helper.c | 74 + hacks/glx/xscreensaver-gl-helper.man | 33 + hacks/goop.c | 603 + hacks/goop.man | 84 + hacks/grav.c | 364 + hacks/grav.man | 78 + hacks/greynetic.c | 293 + hacks/greynetic.man | 56 + hacks/halftone.c | 397 + hacks/halftone.man | 83 + hacks/halo.c | 440 + hacks/halo.man | 75 + hacks/helix.c | 356 + hacks/helix.man | 62 + hacks/hexadrop.c | 421 + hacks/hexadrop.man | 74 + hacks/hopalong.c | 580 + hacks/hopalong.man | 82 + hacks/hyperball.c | 2463 ++ hacks/hyperball.man | 88 + hacks/hypercube.c | 571 + hacks/hypercube.man | 97 + hacks/ifs.c | 535 + hacks/ifs.man | 111 + hacks/images/6x10font.xbm | 190 + hacks/images/amiga.xpm | 269 + hacks/images/android.xpm | 112 + hacks/images/apple2font.xbm | 41 + hacks/images/atari.xbm | 6 + hacks/images/atm.xbm | 246 + hacks/images/blocktube.xpm | 320 + hacks/images/bob.xbm | 43 + hacks/images/bubbles/blood.pov | 24 + hacks/images/bubbles/blood1.xpm | 75 + hacks/images/bubbles/blood10.xpm | 159 + hacks/images/bubbles/blood11.xpm | 170 + hacks/images/bubbles/blood2.xpm | 101 + hacks/images/bubbles/blood3.xpm | 112 + hacks/images/bubbles/blood4.xpm | 116 + hacks/images/bubbles/blood5.xpm | 121 + hacks/images/bubbles/blood6.xpm | 128 + hacks/images/bubbles/blood7.xpm | 135 + hacks/images/bubbles/blood8.xpm | 143 + hacks/images/bubbles/blood9.xpm | 149 + hacks/images/bubbles/blue.pov | 22 + hacks/images/bubbles/blue1.xpm | 64 + hacks/images/bubbles/blue10.xpm | 157 + hacks/images/bubbles/blue11.xpm | 169 + hacks/images/bubbles/blue2.xpm | 90 + hacks/images/bubbles/blue3.xpm | 104 + hacks/images/bubbles/blue4.xpm | 116 + hacks/images/bubbles/blue5.xpm | 122 + hacks/images/bubbles/blue6.xpm | 128 + hacks/images/bubbles/blue7.xpm | 132 + hacks/images/bubbles/blue8.xpm | 142 + hacks/images/bubbles/blue9.xpm | 149 + hacks/images/bubbles/glass.pov | 27 + hacks/images/bubbles/glass1.xpm | 79 + hacks/images/bubbles/glass10.xpm | 155 + hacks/images/bubbles/glass11.xpm | 167 + hacks/images/bubbles/glass2.xpm | 95 + hacks/images/bubbles/glass3.xpm | 112 + hacks/images/bubbles/glass4.xpm | 118 + hacks/images/bubbles/glass5.xpm | 120 + hacks/images/bubbles/glass6.xpm | 128 + hacks/images/bubbles/glass7.xpm | 133 + hacks/images/bubbles/glass8.xpm | 140 + hacks/images/bubbles/glass9.xpm | 147 + hacks/images/bubbles/jade.pov | 24 + hacks/images/bubbles/jade1.xpm | 76 + hacks/images/bubbles/jade10.xpm | 158 + hacks/images/bubbles/jade11.xpm | 171 + hacks/images/bubbles/jade2.xpm | 96 + hacks/images/bubbles/jade3.xpm | 113 + hacks/images/bubbles/jade4.xpm | 116 + hacks/images/bubbles/jade5.xpm | 123 + hacks/images/bubbles/jade6.xpm | 128 + hacks/images/bubbles/jade7.xpm | 133 + hacks/images/bubbles/jade8.xpm | 143 + hacks/images/bubbles/jade9.xpm | 149 + hacks/images/chromesphere.xpm | 350 + hacks/images/earth.xpm | 303 + hacks/images/ground.xpm | 227 + hacks/images/hmac.xpm | 52 + hacks/images/jigglymap.xpm | 350 + hacks/images/lament128.xpm | 791 + hacks/images/lament512.xpm | 3094 ++ hacks/images/m6502/amiga.asm | 120 + hacks/images/m6502/breakout.asm | 195 + hacks/images/m6502/byterun.asm | 100 + hacks/images/m6502/cellular-30.asm | 67 + hacks/images/m6502/cellular-600.asm | 209 + hacks/images/m6502/colors.asm | 46 + hacks/images/m6502/crunch6502.asm | 292 + hacks/images/m6502/demoscene.asm | 457 + hacks/images/m6502/disco.asm | 23 + hacks/images/m6502/dmsc.asm | 108 + hacks/images/m6502/dragon-fractal.asm | 49 + hacks/images/m6502/fullscreenlogo.asm | 107 + hacks/images/m6502/keftal.asm | 82 + hacks/images/m6502/matrix.asm | 67 + hacks/images/m6502/noise.asm | 16 + hacks/images/m6502/random-walk.asm | 82 + hacks/images/m6502/random.asm | 11 + hacks/images/m6502/random2.asm | 11 + hacks/images/m6502/rorschach.asm | 124 + hacks/images/m6502/santa.asm | 142 + hacks/images/m6502/selfmodify.asm | 12 + hacks/images/m6502/sierpinsky.asm | 131 + hacks/images/m6502/softsprite.asm | 132 + hacks/images/m6502/spacer.asm | 235 + hacks/images/m6502/starfield2d.asm | 50 + hacks/images/m6502/wave6502.asm | 164 + hacks/images/m6502/zookeeper.asm | 109 + hacks/images/mac.xbm | 14 + hacks/images/macbomb.xbm | 474 + hacks/images/matrix1.xbm | 1260 + hacks/images/matrix1.xpm | 392 + hacks/images/matrix1b.xbm | 307 + hacks/images/matrix1b.xpm | 227 + hacks/images/matrix2.xbm | 1260 + hacks/images/matrix2.xpm | 393 + hacks/images/matrix2b.xbm | 307 + hacks/images/matrix2b.xpm | 233 + hacks/images/matrix3.xpm | 692 + hacks/images/molecules/adenine.pdb | 37 + hacks/images/molecules/adrenochrome.pdb | 55 + hacks/images/molecules/bucky.pdb | 156 + hacks/images/molecules/caffeine.pdb | 54 + hacks/images/molecules/capsaicin.pdb | 49 + hacks/images/molecules/chlordecone.pdb | 49 + hacks/images/molecules/cocaine.pdb | 93 + hacks/images/molecules/codeine.pdb | 93 + hacks/images/molecules/cyclohexane.pdb | 151 + hacks/images/molecules/cytosine.pdb | 33 + hacks/images/molecules/dna.pdb | 972 + hacks/images/molecules/dodecahedrane.pdb | 87 + hacks/images/molecules/dthc.pdb | 107 + hacks/images/molecules/dynamite.pdb | 47 + hacks/images/molecules/glycol.pdb | 27 + hacks/images/molecules/guanine.pdb | 39 + hacks/images/molecules/heroin.pdb | 107 + hacks/images/molecules/hexahelicene.pdb | 90 + hacks/images/molecules/ibuprofen.pdb | 72 + hacks/images/molecules/lsd.pdb | 104 + hacks/images/molecules/menthol.pdb | 69 + hacks/images/molecules/mescaline.pdb | 71 + hacks/images/molecules/methamphetamine.pdb | 88 + hacks/images/molecules/morphine.pdb | 87 + hacks/images/molecules/nicotine.pdb | 59 + hacks/images/molecules/novocaine.pdb | 81 + hacks/images/molecules/olestra.pdb | 913 + hacks/images/molecules/penicillin.pdb | 89 + hacks/images/molecules/salvinorin.pdb | 92 + hacks/images/molecules/sarin.pdb | 43 + hacks/images/molecules/strychnine.pdb | 101 + hacks/images/molecules/sucrose.pdb | 97 + hacks/images/molecules/thalidomide.pdb | 65 + hacks/images/molecules/thymine.pdb | 37 + hacks/images/molecules/viagra.pdb | 133 + hacks/images/molecules/vitaminb6.pdb | 56 + hacks/images/molecules/vitaminc.pdb | 47 + hacks/images/molecules/vx.pdb | 92 + hacks/images/noseguy/nose-f1.xbm | 46 + hacks/images/noseguy/nose-f1.xpm | 74 + hacks/images/noseguy/nose-f2.xbm | 46 + hacks/images/noseguy/nose-f2.xpm | 74 + hacks/images/noseguy/nose-f3.xbm | 46 + hacks/images/noseguy/nose-f3.xpm | 74 + hacks/images/noseguy/nose-f4.xbm | 46 + hacks/images/noseguy/nose-f4.xpm | 73 + hacks/images/noseguy/nose-l1.xbm | 46 + hacks/images/noseguy/nose-l1.xpm | 74 + hacks/images/noseguy/nose-l2.xbm | 46 + hacks/images/noseguy/nose-l2.xpm | 74 + hacks/images/noseguy/nose-r1.xbm | 46 + hacks/images/noseguy/nose-r1.xpm | 74 + hacks/images/noseguy/nose-r2.xbm | 46 + hacks/images/noseguy/nose-r2.xpm | 74 + hacks/images/osx_10_2.xpm | 298 + hacks/images/osx_10_3.xpm | 279 + hacks/images/pacman/eyes-d.xpm | 70 + hacks/images/pacman/eyes-l.xpm | 70 + hacks/images/pacman/eyes-r.xpm | 70 + hacks/images/pacman/eyes-u.xpm | 70 + hacks/images/pacman/ghost-d1.xpm | 72 + hacks/images/pacman/ghost-d2.xpm | 72 + hacks/images/pacman/ghost-l1.xpm | 72 + hacks/images/pacman/ghost-l2.xpm | 73 + hacks/images/pacman/ghost-mask.xpm | 69 + hacks/images/pacman/ghost-r1.xpm | 72 + hacks/images/pacman/ghost-r2.xpm | 72 + hacks/images/pacman/ghost-s1.xpm | 71 + hacks/images/pacman/ghost-s2.xpm | 71 + hacks/images/pacman/ghost-sf1.xpm | 71 + hacks/images/pacman/ghost-sf2.xpm | 71 + hacks/images/pacman/ghost-u1.xpm | 72 + hacks/images/pacman/ghost-u2.xpm | 72 + hacks/images/pacman/pacman-0.xpm | 69 + hacks/images/pacman/pacman-d1.xpm | 69 + hacks/images/pacman/pacman-d2.xpm | 69 + hacks/images/pacman/pacman-ds1.xpm | 69 + hacks/images/pacman/pacman-ds2.xpm | 69 + hacks/images/pacman/pacman-ds3.xpm | 69 + hacks/images/pacman/pacman-ds4.xpm | 69 + hacks/images/pacman/pacman-ds5.xpm | 69 + hacks/images/pacman/pacman-ds6.xpm | 69 + hacks/images/pacman/pacman-ds7.xpm | 69 + hacks/images/pacman/pacman-ds8.xpm | 69 + hacks/images/pacman/pacman-l1.xpm | 69 + hacks/images/pacman/pacman-l2.xpm | 69 + hacks/images/pacman/pacman-r1.xpm | 69 + hacks/images/pacman/pacman-r2.xpm | 69 + hacks/images/pacman/pacman-u1.xpm | 69 + hacks/images/pacman/pacman-u2.xpm | 69 + hacks/images/sball-bg.xpm | 355 + hacks/images/sball.xpm | 131 + hacks/images/scales.xpm | 204 + hacks/images/sea-texture.xpm | 199 + hacks/images/som.xbm | 1685 + hacks/images/timetunnel0.xpm | 343 + hacks/images/timetunnel1.xpm | 1111 + hacks/images/timetunnel2.xpm | 599 + hacks/images/toast.xpm | 222 + hacks/images/tree.xpm | 226 + hacks/images/tunnel0.xpm | 198 + hacks/images/tunnel1.xpm | 134 + hacks/images/tunnel2.xpm | 206 + hacks/images/tunnel3.xpm | 150 + hacks/images/tunnel4.xpm | 134 + hacks/images/tunnel5.xpm | 134 + hacks/images/tunnelstar.xpm | 323 + hacks/images/wood.xpm | 70 + hacks/imsmap.c | 419 + hacks/imsmap.man | 64 + hacks/interaggregate.c | 974 + hacks/interaggregate.man | 72 + hacks/interference.c | 1029 + hacks/interference.man | 86 + hacks/intermomentary.c | 575 + hacks/intermomentary.man | 82 + hacks/juggle.c | 2823 ++ hacks/juggle.man | 181 + hacks/julia.c | 457 + hacks/julia.man | 81 + hacks/kaleidescope.c | 490 + hacks/kaleidescope.man | 89 + hacks/kumppa.c | 536 + hacks/kumppa.man | 65 + hacks/laser.c | 366 + hacks/laser.man | 68 + hacks/lcdscrub.c | 241 + hacks/lcdscrub.man | 73 + hacks/lightning.c | 614 + hacks/lightning.man | 62 + hacks/link_axp.com | 107 + hacks/link_decc.com | 107 + hacks/lisa.c | 751 + hacks/lisa.man | 71 + hacks/lissie.c | 329 + hacks/lissie.man | 69 + hacks/ljlatest | 18 + hacks/ljlatest.man | 61 + hacks/lmorph.c | 568 + hacks/lmorph.man | 65 + hacks/loop.c | 1704 + hacks/loop.man | 65 + hacks/m6502.c | 290 + hacks/m6502.sh | 25 + hacks/maze.c | 1653 + hacks/maze.man | 148 + hacks/memscroller.c | 653 + hacks/memscroller.man | 78 + hacks/metaballs.c | 432 + hacks/metaballs.man | 73 + hacks/moire.c | 297 + hacks/moire.man | 68 + hacks/moire2.c | 355 + hacks/moire2.man | 63 + hacks/mountain.c | 298 + hacks/mountain.man | 60 + hacks/munch.c | 459 + hacks/munch.man | 153 + hacks/munge-ad.pl | 243 + hacks/nerverot.c | 1354 + hacks/nerverot.man | 132 + hacks/noseguy.c | 622 + hacks/noseguy.man | 84 + hacks/pacman.c | 1804 + hacks/pacman.h | 231 + hacks/pacman.man | 67 + hacks/pacman_ai.c | 876 + hacks/pacman_ai.h | 32 + hacks/pacman_level.c | 772 + hacks/pacman_level.h | 33 + hacks/pedal.c | 329 + hacks/pedal.man | 60 + hacks/penetrate.c | 988 + hacks/penetrate.man | 98 + hacks/penrose.c | 1356 + hacks/penrose.man | 106 + hacks/petri.c | 761 + hacks/petri.man | 129 + hacks/phosphor.c | 1287 + hacks/phosphor.man | 173 + hacks/piecewise.c | 1002 + hacks/piecewise.man | 77 + hacks/polyominoes.c | 2397 + hacks/polyominoes.man | 65 + hacks/pong.c | 790 + hacks/pong.man | 82 + hacks/popsquares.c | 270 + hacks/pyro.c | 368 + hacks/pyro.man | 64 + hacks/qix.c | 624 + hacks/qix.man | 132 + hacks/rd-bomb.c | 594 + hacks/rd-bomb.man | 100 + hacks/ripples.c | 1137 + hacks/ripples.man | 96 + hacks/rocks.c | 549 + hacks/rocks.man | 90 + hacks/rorschach.c | 208 + hacks/rorschach.man | 75 + hacks/rotor.c | 401 + hacks/rotor.man | 68 + hacks/rotzoomer.c | 486 + hacks/rotzoomer.man | 88 + hacks/screenhack.c | 935 + hacks/screenhack.h | 61 + hacks/screenhackI.h | 138 + hacks/shadebobs.c | 468 + hacks/shadebobs.man | 65 + hacks/sierpinski.c | 231 + hacks/sierpinski.man | 69 + hacks/slidescreen.c | 488 + hacks/slidescreen.man | 97 + hacks/slip.c | 368 + hacks/slip.man | 86 + hacks/speedmine.c | 1649 + hacks/speedmine.man | 246 + hacks/sphere.c | 308 + hacks/sphere.man | 62 + hacks/spiral.c | 335 + hacks/spiral.man | 71 + hacks/spotlight.c | 336 + hacks/spotlight.man | 80 + hacks/squiral.c | 282 + hacks/squiral.man | 80 + hacks/starfish.c | 550 + hacks/starfish.man | 84 + hacks/strange.c | 702 + hacks/strange.man | 62 + hacks/substrate.c | 742 + hacks/substrate.man | 73 + hacks/swirl.c | 1488 + hacks/swirl.man | 70 + hacks/t3d.c | 970 + hacks/t3d.man | 131 + hacks/thornbird.c | 282 + hacks/thornbird.man | 64 + hacks/triangle.c | 369 + hacks/triangle.man | 56 + hacks/truchet.c | 536 + hacks/truchet.man | 139 + hacks/twang.c | 794 + hacks/twang.man | 132 + hacks/vermiculate.c | 1221 + hacks/vermiculate.man | 48 + hacks/vidwhacker | 506 + hacks/vidwhacker.man | 89 + hacks/vines.c | 203 + hacks/vines.man | 66 + hacks/vms_axp.opt | 4 + hacks/vms_axp_12.opt | 4 + hacks/vms_decc.opt | 4 + hacks/vms_decc_12.opt | 4 + hacks/wander.c | 264 + hacks/wander.man | 76 + hacks/webcollage | 3958 ++ hacks/webcollage-cocoa.m | 420 + hacks/webcollage-helper-cocoa.m | 407 + hacks/webcollage-helper.c | 504 + hacks/webcollage.man | 247 + hacks/whirlwindwarp.c | 505 + hacks/whirlwindwarp.man | 64 + hacks/whirlygig.c | 735 + hacks/whirlygig.man | 137 + hacks/worm.c | 442 + hacks/worm.man | 65 + hacks/wormhole.c | 724 + hacks/wormhole.man | 69 + hacks/xanalogtv.c | 617 + hacks/xanalogtv.man | 84 + hacks/xflame.c | 822 + hacks/xflame.man | 72 + hacks/xjack.c | 499 + hacks/xjack.man | 52 + hacks/xlockmore.c | 560 + hacks/xlockmore.h | 198 + hacks/xlockmoreI.h | 170 + hacks/xlyap.c | 1921 + hacks/xlyap.man | 223 + hacks/xmatrix.c | 1852 + hacks/xmatrix.man | 146 + hacks/xml2man.pl | 264 + hacks/xpm-pixmap.c | 363 + hacks/xpm-pixmap.h | 26 + hacks/xrayswarm.c | 1223 + hacks/xrayswarm.man | 50 + hacks/xscreensaver-sgigl.c | 266 + hacks/xspirograph.c | 333 + hacks/xspirograph.man | 71 + hacks/xsublim.c | 798 + hacks/xsublim.man | 91 + hacks/zoom.c | 272 + hacks/zoom.man | 111 + install-sh | 250 + intltool-extract.in | 309 + intltool-merge.in | 567 + intltool-update.in | 613 + makevms.com | 57 + po/ChangeLog | 300 + po/Makefile.in.in | 385 + po/POTFILES.in | 235 + po/ca.po | 8905 ++++ po/da.po | 9938 +++++ po/de.po | 9219 ++++ po/es.po | 10021 +++++ po/et.po | 8995 ++++ po/fi.po | 8939 ++++ po/fr.po | 9248 ++++ po/hu.po | 9760 ++++ po/it.po | 8967 ++++ po/ja.po | 9039 ++++ po/ko.po | 9340 ++++ po/nb.po | 9071 ++++ po/nl.po | 11325 +++++ po/pl.po | 9387 ++++ po/pt.po | 9995 +++++ po/pt_BR.po | 9563 ++++ po/ru.po | 9132 ++++ po/sk.po | 9242 ++++ po/sv.po | 11236 +++++ po/update.sh | 24 + po/vi.po | 9347 ++++ po/wa.po | 9138 ++++ po/zh_CN.po | 9513 ++++ po/zh_TW.po | 9358 ++++ setup.com | 125 + utils/Makefile.in | 307 + utils/README | 6 + utils/ad2c | 42 + utils/alpha.c | 215 + utils/alpha.h | 22 + utils/colorbars.c | 144 + utils/colorbars.h | 24 + utils/colors.c | 732 + utils/colors.h | 147 + utils/compile_axp.com | 26 + utils/compile_decc.com | 26 + utils/erase.c | 758 + utils/erase.h | 20 + utils/fade.c | 962 + utils/fade.h | 21 + utils/grabclient.c | 945 + utils/grabscreen.c | 925 + utils/grabscreen.h | 102 + utils/hsv.c | 81 + utils/hsv.h | 27 + utils/images/logo-180.gif | Bin 0 -> 3328 bytes utils/images/logo-180.xpm | 207 + utils/images/logo-50.gif | Bin 0 -> 857 bytes utils/images/logo-50.xpm | 77 + utils/images/logo-big.gif | Bin 0 -> 17019 bytes utils/images/logo.eps | 8058 ++++ utils/images/screensaver-cmndln.png | Bin 0 -> 1040 bytes utils/images/screensaver-colorselector.png | Bin 0 -> 1104 bytes utils/images/screensaver-diagnostic.png | Bin 0 -> 1307 bytes utils/images/screensaver-locking.png | Bin 0 -> 944 bytes utils/images/screensaver-power.png | Bin 0 -> 973 bytes utils/images/screensaver-snap.png | Bin 0 -> 1272 bytes utils/logo.c | 75 + utils/minixpm.c | 241 + utils/minixpm.h | 28 + utils/overlay.c | 158 + utils/resources.c | 265 + utils/resources.h | 33 + utils/spline.c | 319 + utils/spline.h | 51 + utils/textclient.c | 502 + utils/textclient.h | 31 + utils/usleep.c | 64 + utils/usleep.h | 20 + utils/utils.h | 27 + utils/version.h | 2 + utils/visual-gl.c | 308 + utils/visual.c | 544 + utils/visual.h | 32 + utils/vms-gtod.c | 31 + utils/vms-gtod.h | 85 + utils/vms-strdup.c | 25 + utils/vroot.h | 156 + utils/xdbe.c | 75 + utils/xdbe.h | 27 + utils/xmu.c | 173 + utils/xmu.h | 14 + utils/xscreensaver-intl.h | 36 + utils/xshm.c | 229 + utils/xshm.h | 37 + utils/yarandom.c | 139 + utils/yarandom.h | 65 + xscreensaver.spec | 204 + xscreensaver.xcodeproj/project.pbxproj | 36912 ++++++++++++++++ 1494 files changed, 762144 insertions(+) create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 OSX/Default-568h@2x.png create mode 100644 OSX/English.lproj/InfoPlist.strings create mode 100644 OSX/English.lproj/SaverRunner.nib/designable.nib create mode 100644 OSX/English.lproj/SaverRunner.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/SaverListController.h create mode 100644 OSX/SaverListController.m create mode 100644 OSX/SaverRunner.h create mode 100644 OSX/SaverRunner.icns create mode 100644 OSX/SaverRunner.m create mode 100644 OSX/SaverRunner.plist create mode 120000 OSX/Sparkle.framework/Headers create mode 120000 OSX/Sparkle.framework/Resources create mode 120000 OSX/Sparkle.framework/Sparkle create mode 100755 OSX/Sparkle.framework/Versions/A/Headers/SUAppcast.h create mode 100755 OSX/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h create mode 100755 OSX/Sparkle.framework/Versions/A/Headers/SUUpdater.h create mode 100755 OSX/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h create mode 100755 OSX/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h create mode 100755 OSX/Sparkle.framework/Versions/A/Headers/Sparkle.h create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/Info.plist create mode 100755 OSX/Sparkle.framework/Versions/A/Resources/License.txt create mode 100755 OSX/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/SUStatus.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUPasswordPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUPasswordPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/en.lproj/SUPasswordPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Info.plist create mode 100755 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/MacOS/finish_installation create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/PkgInfo create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/SUStatus.nib create mode 100755 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/Sparkle.icns create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ar.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/cs.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/da.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/de.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/en.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/es.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/fr.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/is.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/it.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ja.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/nl.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pl.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pt_BR.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pt_PT.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ro.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ru.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/sl.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/sv.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/th.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/tr.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/uk.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/zh_CN.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/zh_TW.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings create mode 120000 OSX/Sparkle.framework/Versions/A/Resources/fr_CA.lproj create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings create mode 120000 OSX/Sparkle.framework/Versions/A/Resources/pt.lproj create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUPasswordPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/th.lproj/SUPasswordPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib create mode 100644 OSX/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings create mode 100755 OSX/Sparkle.framework/Versions/A/Sparkle create mode 120000 OSX/Sparkle.framework/Versions/Current create mode 100644 OSX/Updater.h create mode 100644 OSX/Updater.m create mode 100644 OSX/Updater.plist create mode 100644 OSX/Updater.xib 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/XScreenSaverFolder.icns create mode 100644 OSX/XScreenSaverGLView.h create mode 100644 OSX/XScreenSaverGLView.m create mode 100644 OSX/XScreenSaverPkg.icns create mode 100644 OSX/XScreenSaverSubclass.m create mode 100644 OSX/XScreenSaverView.h create mode 100644 OSX/XScreenSaverView.m create mode 100644 OSX/XScreenSaverView.m.orig create mode 100644 OSX/XScreenSaverWebloc.icns create mode 100644 OSX/apple2-app.xml create mode 100644 OSX/bindist-DS_Store create mode 100644 OSX/bindist.rtf create mode 100644 OSX/bindist.webloc create mode 100755 OSX/build-fntable.pl create mode 100644 OSX/config.sub create mode 100644 OSX/iSaverRunner.ai create mode 100644 OSX/iSaverRunner.plist create mode 100644 OSX/iSaverRunner.xib create mode 100644 OSX/iSaverRunner1024.png create mode 100644 OSX/iSaverRunner114.png create mode 100644 OSX/iSaverRunner29.png create mode 100644 OSX/iSaverRunner29t.png create mode 100644 OSX/iSaverRunner50.png create mode 100644 OSX/iSaverRunner57.png create mode 100644 OSX/iSaverRunner72.png create mode 100755 OSX/icmp-warning.pl create mode 100644 OSX/installer.png create mode 100644 OSX/installer.rtf create mode 100755 OSX/installer.sh create mode 100644 OSX/installer.xml create mode 100644 OSX/ios-function-table.m create mode 100644 OSX/iosgrabimage.m create mode 100644 OSX/iostextclient.m 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.h.rej create mode 100644 OSX/jwxyz.m create mode 100644 OSX/jwxyz.m.orig create mode 100644 OSX/main.m create mode 100644 OSX/osxgrabscreen.m create mode 100644 OSX/phosphor-app.xml create mode 100755 OSX/sign_update.rb create mode 100644 OSX/sparkle_dsa_pub.pem create mode 100755 OSX/update-info-plist.pl create mode 100755 OSX/update-thumbnail.pl create mode 100755 OSX/updates.pl create mode 100644 OSX/updates.xml create mode 100644 OSX/xscreensaver_Prefix.pch create mode 100644 README create mode 100644 README.VMS create mode 100644 README.hacking create mode 100644 aclocal.m4 create mode 100644 config.guess create mode 100644 config.h-vms create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 driver/.gdbinit create mode 100644 driver/Makefile.in create mode 100644 driver/README create mode 100644 driver/XScreenSaver-Xm.ad create mode 100644 driver/XScreenSaver.ad.in create mode 100644 driver/XScreenSaver_Xm_ad.h create mode 100644 driver/XScreenSaver_ad.h create mode 100644 driver/auth.h create mode 100644 driver/compile_axp.com create mode 100644 driver/compile_decc.com create mode 100644 driver/demo-Gtk-conf.c create mode 100644 driver/demo-Gtk-conf.h create mode 100644 driver/demo-Gtk-stubs.h create mode 100644 driver/demo-Gtk-support.c create mode 100644 driver/demo-Gtk-support.h create mode 100644 driver/demo-Gtk-widgets.c create mode 100644 driver/demo-Gtk-widgets.h create mode 100644 driver/demo-Gtk.c create mode 100644 driver/demo-Xm-widgets.c create mode 100644 driver/demo-Xm.c create mode 100644 driver/dpms.c create mode 100644 driver/exec.c create mode 100644 driver/exec.h create mode 100644 driver/link_axp.com create mode 100644 driver/link_decc.com create mode 100644 driver/lock.c create mode 100644 driver/mlstring.c create mode 100644 driver/mlstring.h create mode 100644 driver/passwd-helper.c create mode 100644 driver/passwd-kerberos.c create mode 100644 driver/passwd-pam.c create mode 100644 driver/passwd-pwent.c create mode 100644 driver/passwd.c create mode 100644 driver/pdf2jpeg.m create mode 100644 driver/pdf2jpeg.man create mode 100644 driver/prefs.c create mode 100644 driver/prefs.h create mode 100644 driver/remote.c create mode 100644 driver/remote.h create mode 100644 driver/screens.c create mode 100644 driver/screensaver-properties.desktop.in create mode 100644 driver/setuid.c create mode 100644 driver/splash.c create mode 100644 driver/stderr.c create mode 100644 driver/subprocs.c create mode 100644 driver/test-apm.c create mode 100644 driver/test-fade.c create mode 100644 driver/test-grab.c create mode 100644 driver/test-mlstring.c create mode 100644 driver/test-passwd.c create mode 100644 driver/test-randr.c create mode 100644 driver/test-screens.c create mode 100644 driver/test-uid.c create mode 100644 driver/test-vp.c create mode 100644 driver/test-xdpms.c create mode 100644 driver/test-xinerama.c create mode 100644 driver/timers.c create mode 100644 driver/types.h create mode 100644 driver/vms-getpwnam.c create mode 100644 driver/vms-hpwd.c create mode 100644 driver/vms-pwd.h create mode 100644 driver/vms-validate.c create mode 100644 driver/vms_axp.opt create mode 100644 driver/vms_axp_12.opt create mode 100644 driver/vms_decc.opt create mode 100644 driver/vms_decc_12.opt create mode 100644 driver/windows.c create mode 100644 driver/xdpyinfo.c create mode 100644 driver/xscreensaver-command.c create mode 100644 driver/xscreensaver-command.man create mode 100644 driver/xscreensaver-demo.glade2 create mode 100644 driver/xscreensaver-demo.glade2p create mode 100644 driver/xscreensaver-demo.man create mode 100755 driver/xscreensaver-getimage-desktop create mode 100644 driver/xscreensaver-getimage-desktop.man create mode 100755 driver/xscreensaver-getimage-file create mode 100644 driver/xscreensaver-getimage-file.man create mode 100755 driver/xscreensaver-getimage-video create mode 100644 driver/xscreensaver-getimage-video.man create mode 100644 driver/xscreensaver-getimage.c create mode 100644 driver/xscreensaver-getimage.man create mode 100755 driver/xscreensaver-text create mode 100644 driver/xscreensaver-text.man create mode 100644 driver/xscreensaver.c create mode 100644 driver/xscreensaver.h create mode 100644 driver/xscreensaver.man create mode 100644 driver/xscreensaver.pam.in create mode 100644 driver/xset.c create mode 100644 hacks/.gdbinit create mode 100644 hacks/Makefile.in create mode 100644 hacks/README create mode 100644 hacks/abstractile.c create mode 100644 hacks/abstractile.man create mode 100644 hacks/analogtv.c create mode 100644 hacks/analogtv.h create mode 100644 hacks/anemone.c create mode 100644 hacks/anemone.man create mode 100644 hacks/anemotaxis.c create mode 100644 hacks/anemotaxis.man create mode 100644 hacks/ant.c create mode 100644 hacks/ant.man create mode 100644 hacks/apollonian.c create mode 100644 hacks/apollonian.man create mode 100644 hacks/apple2-main.c create mode 100644 hacks/apple2.c create mode 100644 hacks/apple2.h create mode 100644 hacks/apple2.man create mode 100644 hacks/asm6502.c create mode 100644 hacks/asm6502.h create mode 100644 hacks/attraction.c create mode 100644 hacks/attraction.man create mode 100644 hacks/automata.h create mode 100644 hacks/barcode.c create mode 100644 hacks/barcode.man create mode 100644 hacks/blaster.c create mode 100644 hacks/blaster.man create mode 100644 hacks/blitspin.c create mode 100644 hacks/blitspin.man create mode 100644 hacks/bouboule.c create mode 100644 hacks/bouboule.man create mode 100644 hacks/boxfit.c create mode 100644 hacks/boxfit.man create mode 100644 hacks/braid.c create mode 100644 hacks/braid.man create mode 100644 hacks/bsod.c create mode 100644 hacks/bsod.man create mode 100644 hacks/bubbles-default.c create mode 100644 hacks/bubbles.c create mode 100644 hacks/bubbles.h create mode 100644 hacks/bubbles.man create mode 100644 hacks/bumps.c create mode 100644 hacks/bumps.man create mode 100644 hacks/ccurve.c create mode 100644 hacks/ccurve.man create mode 100644 hacks/celtic.c create mode 100644 hacks/celtic.man create mode 100755 hacks/check-configs.pl create mode 100644 hacks/cloudlife.c create mode 100644 hacks/cloudlife.man create mode 100644 hacks/compass.c create mode 100644 hacks/compass.man create mode 100644 hacks/compile_axp.com create mode 100644 hacks/compile_decc.com create mode 100644 hacks/config/README create mode 100644 hacks/config/abstractile.xml create mode 100644 hacks/config/anemone.xml create mode 100644 hacks/config/anemotaxis.xml create mode 100644 hacks/config/ant.xml create mode 100644 hacks/config/antinspect.xml create mode 100644 hacks/config/antmaze.xml create mode 100644 hacks/config/antspotlight.xml create mode 100644 hacks/config/apollonian.xml create mode 100644 hacks/config/apple2.xml create mode 100644 hacks/config/atlantis.xml create mode 100644 hacks/config/attraction.xml create mode 100644 hacks/config/atunnel.xml create mode 100644 hacks/config/barcode.xml create mode 100644 hacks/config/blaster.xml create mode 100644 hacks/config/blinkbox.xml create mode 100644 hacks/config/blitspin.xml create mode 100644 hacks/config/blocktube.xml create mode 100644 hacks/config/boing.xml create mode 100644 hacks/config/bouboule.xml create mode 100644 hacks/config/bouncingcow.xml create mode 100644 hacks/config/boxed.xml create mode 100644 hacks/config/boxfit.xml create mode 100644 hacks/config/braid.xml create mode 100644 hacks/config/bsod.xml create mode 100644 hacks/config/bubble3d.xml create mode 100644 hacks/config/bubbles.xml create mode 100644 hacks/config/bumps.xml create mode 100644 hacks/config/cage.xml create mode 100644 hacks/config/carousel.xml create mode 100644 hacks/config/ccurve.xml create mode 100644 hacks/config/celtic.xml create mode 100644 hacks/config/circuit.xml create mode 100644 hacks/config/cloudlife.xml create mode 100644 hacks/config/companioncube.xml create mode 100644 hacks/config/compass.xml create mode 100644 hacks/config/coral.xml create mode 100644 hacks/config/crackberg.xml create mode 100644 hacks/config/critical.xml create mode 100644 hacks/config/crystal.xml create mode 100644 hacks/config/cube21.xml create mode 100644 hacks/config/cubenetic.xml create mode 100644 hacks/config/cubestorm.xml create mode 100644 hacks/config/cubicgrid.xml create mode 100644 hacks/config/cwaves.xml create mode 100644 hacks/config/cynosure.xml create mode 100644 hacks/config/dangerball.xml create mode 100644 hacks/config/decayscreen.xml create mode 100644 hacks/config/deco.xml create mode 100644 hacks/config/deluxe.xml create mode 100644 hacks/config/demon.xml create mode 100644 hacks/config/discrete.xml create mode 100644 hacks/config/distort.xml create mode 100644 hacks/config/dnalogo.xml create mode 100644 hacks/config/drift.xml create mode 100644 hacks/config/endgame.xml create mode 100644 hacks/config/engine.xml create mode 100644 hacks/config/epicycle.xml create mode 100644 hacks/config/eruption.xml create mode 100644 hacks/config/euler2d.xml create mode 100644 hacks/config/extrusion.xml create mode 100644 hacks/config/fadeplot.xml create mode 100644 hacks/config/fiberlamp.xml create mode 100644 hacks/config/fireworkx.xml create mode 100644 hacks/config/flag.xml create mode 100644 hacks/config/flame.xml create mode 100644 hacks/config/flipflop.xml create mode 100644 hacks/config/flipscreen3d.xml create mode 100644 hacks/config/fliptext.xml create mode 100644 hacks/config/flow.xml create mode 100644 hacks/config/fluidballs.xml create mode 100644 hacks/config/flurry.xml create mode 100644 hacks/config/flyingtoasters.xml create mode 100644 hacks/config/fontglide.xml create mode 100644 hacks/config/forest.xml create mode 100644 hacks/config/fuzzyflakes.xml create mode 100644 hacks/config/galaxy.xml create mode 100644 hacks/config/gears.xml create mode 100644 hacks/config/geodesic.xml create mode 100644 hacks/config/gflux.xml create mode 100644 hacks/config/glblur.xml create mode 100644 hacks/config/glcells.xml create mode 100644 hacks/config/gleidescope.xml create mode 100644 hacks/config/glforestfire.xml create mode 100644 hacks/config/glhanoi.xml create mode 100644 hacks/config/glknots.xml create mode 100644 hacks/config/glmatrix.xml create mode 100644 hacks/config/glplanet.xml create mode 100644 hacks/config/glschool.xml create mode 100644 hacks/config/glslideshow.xml create mode 100644 hacks/config/glsnake.xml create mode 100644 hacks/config/gltext.xml create mode 100644 hacks/config/goop.xml create mode 100644 hacks/config/grav.xml create mode 100644 hacks/config/greynetic.xml create mode 100644 hacks/config/halftone.xml create mode 100644 hacks/config/halo.xml create mode 100644 hacks/config/helix.xml create mode 100644 hacks/config/hexadrop.xml create mode 100644 hacks/config/hilbert.xml create mode 100644 hacks/config/hopalong.xml create mode 100644 hacks/config/hyperball.xml create mode 100644 hacks/config/hypercube.xml create mode 100644 hacks/config/hypertorus.xml create mode 100644 hacks/config/hypnowheel.xml create mode 100644 hacks/config/ifs.xml create mode 100644 hacks/config/imsmap.xml create mode 100644 hacks/config/interaggregate.xml create mode 100644 hacks/config/interference.xml create mode 100644 hacks/config/intermomentary.xml create mode 100644 hacks/config/jigglypuff.xml create mode 100644 hacks/config/jigsaw.xml create mode 100644 hacks/config/juggle.xml create mode 100644 hacks/config/juggler3d.xml create mode 100644 hacks/config/julia.xml create mode 100644 hacks/config/kaleidescope.xml create mode 100644 hacks/config/kaleidocycle.xml create mode 100644 hacks/config/klein.xml create mode 100644 hacks/config/kumppa.xml create mode 100644 hacks/config/lament.xml create mode 100644 hacks/config/laser.xml create mode 100644 hacks/config/lavalite.xml create mode 100644 hacks/config/lcdscrub.xml create mode 100644 hacks/config/lightning.xml create mode 100644 hacks/config/lisa.xml create mode 100644 hacks/config/lissie.xml create mode 100644 hacks/config/lmorph.xml create mode 100644 hacks/config/lockward.xml create mode 100644 hacks/config/loop.xml create mode 100644 hacks/config/m6502.xml create mode 100644 hacks/config/maze.xml create mode 100644 hacks/config/memscroller.xml create mode 100644 hacks/config/menger.xml create mode 100644 hacks/config/metaballs.xml create mode 100644 hacks/config/mirrorblob.xml create mode 100644 hacks/config/mismunch.xml create mode 100644 hacks/config/moebius.xml create mode 100644 hacks/config/moebiusgears.xml create mode 100644 hacks/config/moire.xml create mode 100644 hacks/config/moire2.xml create mode 100644 hacks/config/molecule.xml create mode 100644 hacks/config/morph3d.xml create mode 100644 hacks/config/mountain.xml create mode 100644 hacks/config/munch.xml create mode 100644 hacks/config/nerverot.xml create mode 100644 hacks/config/noof.xml create mode 100644 hacks/config/noseguy.xml create mode 100644 hacks/config/pacman.xml create mode 100644 hacks/config/pedal.xml create mode 100644 hacks/config/penetrate.xml create mode 100644 hacks/config/penrose.xml create mode 100644 hacks/config/petri.xml create mode 100644 hacks/config/phosphor.xml create mode 100644 hacks/config/photopile.xml create mode 100644 hacks/config/piecewise.xml create mode 100644 hacks/config/pinion.xml create mode 100644 hacks/config/pipes.xml create mode 100644 hacks/config/polyhedra.xml create mode 100644 hacks/config/polyominoes.xml create mode 100644 hacks/config/polytopes.xml create mode 100644 hacks/config/pong.xml create mode 100644 hacks/config/popsquares.xml create mode 100644 hacks/config/providence.xml create mode 100644 hacks/config/pulsar.xml create mode 100644 hacks/config/pyro.xml create mode 100644 hacks/config/qix.xml create mode 100644 hacks/config/quasicrystal.xml create mode 100644 hacks/config/queens.xml create mode 100644 hacks/config/rd-bomb.xml create mode 100644 hacks/config/rdbomb.xml create mode 100644 hacks/config/ripples.xml create mode 100644 hacks/config/rocks.xml create mode 100644 hacks/config/rorschach.xml create mode 100644 hacks/config/rotor.xml create mode 100644 hacks/config/rotzoomer.xml create mode 100644 hacks/config/rubik.xml create mode 100644 hacks/config/rubikblocks.xml create mode 100644 hacks/config/sballs.xml create mode 100644 hacks/config/shadebobs.xml create mode 100644 hacks/config/sierpinski.xml create mode 100644 hacks/config/sierpinski3d.xml create mode 100644 hacks/config/skytentacles.xml create mode 100644 hacks/config/slidescreen.xml create mode 100644 hacks/config/slip.xml create mode 100644 hacks/config/sonar.xml create mode 100644 hacks/config/speedmine.xml create mode 100644 hacks/config/sphere.xml create mode 100644 hacks/config/spheremonics.xml create mode 100644 hacks/config/spiral.xml create mode 100644 hacks/config/spotlight.xml create mode 100644 hacks/config/sproingies.xml create mode 100644 hacks/config/squiral.xml create mode 100644 hacks/config/stairs.xml create mode 100644 hacks/config/starfish.xml create mode 100644 hacks/config/starwars.xml create mode 100644 hacks/config/stonerview.xml create mode 100644 hacks/config/strange.xml create mode 100644 hacks/config/substrate.xml create mode 100644 hacks/config/superquadrics.xml create mode 100644 hacks/config/surfaces.xml create mode 100644 hacks/config/swirl.xml create mode 100644 hacks/config/t3d.xml create mode 100644 hacks/config/tangram.xml create mode 100644 hacks/config/thornbird.xml create mode 100644 hacks/config/timetunnel.xml create mode 100644 hacks/config/topblock.xml create mode 100644 hacks/config/triangle.xml create mode 100644 hacks/config/tronbit.xml create mode 100644 hacks/config/truchet.xml create mode 100644 hacks/config/twang.xml create mode 100644 hacks/config/unknownpleasures.xml create mode 100644 hacks/config/vermiculate.xml create mode 100644 hacks/config/vidwhacker.xml create mode 100644 hacks/config/vines.xml create mode 100644 hacks/config/voronoi.xml create mode 100644 hacks/config/wander.xml create mode 100644 hacks/config/webcollage.xml create mode 100644 hacks/config/whirlwindwarp.xml create mode 100644 hacks/config/whirlygig.xml create mode 100644 hacks/config/worm.xml create mode 100644 hacks/config/wormhole.xml create mode 100644 hacks/config/xanalogtv.xml create mode 100644 hacks/config/xflame.xml create mode 100644 hacks/config/xjack.xml create mode 100644 hacks/config/xlyap.xml create mode 100644 hacks/config/xmatrix.xml create mode 100644 hacks/config/xrayswarm.xml create mode 100644 hacks/config/xspirograph.xml create mode 100644 hacks/config/xss.dtd create mode 100644 hacks/config/xss.xsd create mode 100644 hacks/config/zoom.xml create mode 100644 hacks/coral.c create mode 100644 hacks/coral.man create mode 100644 hacks/critical.c create mode 100644 hacks/critical.man create mode 100644 hacks/crystal.c create mode 100644 hacks/crystal.man create mode 100644 hacks/cwaves.c create mode 100644 hacks/cwaves.man create mode 100644 hacks/cynosure.c create mode 100644 hacks/cynosure.man create mode 100644 hacks/decayscreen.c create mode 100644 hacks/decayscreen.man create mode 100644 hacks/deco.c create mode 100644 hacks/deco.man create mode 100644 hacks/deluxe.c create mode 100644 hacks/deluxe.man create mode 100644 hacks/demon.c create mode 100644 hacks/demon.man create mode 100644 hacks/discrete.c create mode 100644 hacks/discrete.man create mode 100644 hacks/distort.c create mode 100644 hacks/distort.man create mode 100644 hacks/drift.c create mode 100644 hacks/drift.man create mode 100644 hacks/epicycle.c create mode 100644 hacks/epicycle.man create mode 100644 hacks/eruption.c create mode 100644 hacks/eruption.man create mode 100644 hacks/euler2d.c create mode 100644 hacks/euler2d.man create mode 100644 hacks/euler2d.tex create mode 100644 hacks/fadeplot.c create mode 100644 hacks/fadeplot.man create mode 100644 hacks/fiberlamp.c create mode 100644 hacks/fiberlamp.man create mode 100644 hacks/fireworkx.c create mode 100644 hacks/fireworkx.man create mode 100644 hacks/flag.c create mode 100644 hacks/flag.man create mode 100644 hacks/flame.c create mode 100644 hacks/flame.man create mode 100644 hacks/flow.c create mode 100644 hacks/flow.man create mode 100644 hacks/fluidballs.c create mode 100644 hacks/fluidballs.man create mode 100644 hacks/fontglide.c create mode 100644 hacks/fontglide.man create mode 100644 hacks/forest.c create mode 100644 hacks/forest.man create mode 100644 hacks/fps.c create mode 100644 hacks/fps.h create mode 100644 hacks/fpsI.h create mode 100644 hacks/fuzzyflakes.c create mode 100644 hacks/fuzzyflakes.man create mode 100644 hacks/galaxy.c create mode 100644 hacks/galaxy.man create mode 100644 hacks/glx/Makefile.in create mode 100644 hacks/glx/README create mode 100644 hacks/glx/antinspect.c create mode 100644 hacks/glx/antinspect.man create mode 100644 hacks/glx/antmaze.c create mode 100644 hacks/glx/antmaze.man create mode 100644 hacks/glx/ants.h create mode 100644 hacks/glx/antspotlight.c create mode 100644 hacks/glx/antspotlight.man create mode 100644 hacks/glx/atlantis.c create mode 100644 hacks/glx/atlantis.h create mode 100644 hacks/glx/atlantis.man create mode 100644 hacks/glx/atunnel.c create mode 100644 hacks/glx/atunnel.man create mode 100644 hacks/glx/b_draw.c create mode 100644 hacks/glx/b_lockglue.c create mode 100644 hacks/glx/b_sphere.c create mode 100644 hacks/glx/blinkbox.c create mode 100644 hacks/glx/blinkbox.man create mode 100644 hacks/glx/blocktube.c create mode 100644 hacks/glx/blocktube.man create mode 100644 hacks/glx/boing.c create mode 100644 hacks/glx/boing.man create mode 100644 hacks/glx/bouncingcow.c create mode 100644 hacks/glx/bouncingcow.man create mode 100644 hacks/glx/boxed.c create mode 100644 hacks/glx/boxed.h create mode 100644 hacks/glx/boxed.man create mode 100644 hacks/glx/bubble3d.c create mode 100644 hacks/glx/bubble3d.h create mode 100644 hacks/glx/bubble3d.man create mode 100644 hacks/glx/buildlwo.c create mode 100644 hacks/glx/buildlwo.h create mode 100644 hacks/glx/cage.c create mode 100644 hacks/glx/cage.man create mode 100644 hacks/glx/carousel.c create mode 100644 hacks/glx/carousel.man create mode 100644 hacks/glx/chessgames.h create mode 100644 hacks/glx/chessmodels.c create mode 100644 hacks/glx/chessmodels.h create mode 100644 hacks/glx/circuit.c create mode 100644 hacks/glx/circuit.man create mode 100644 hacks/glx/companion.c create mode 100644 hacks/glx/companion_disc.c create mode 100644 hacks/glx/companion_heart.c create mode 100644 hacks/glx/companion_quad.c create mode 100644 hacks/glx/companioncube.man create mode 100644 hacks/glx/cow_face.c create mode 100644 hacks/glx/cow_hide.c create mode 100644 hacks/glx/cow_hoofs.c create mode 100644 hacks/glx/cow_horns.c create mode 100644 hacks/glx/cow_tail.c create mode 100644 hacks/glx/cow_udder.c create mode 100644 hacks/glx/crackberg.c create mode 100644 hacks/glx/crackberg.man create mode 100644 hacks/glx/cube21.c create mode 100644 hacks/glx/cube21.man create mode 100644 hacks/glx/cubenetic.c create mode 100644 hacks/glx/cubenetic.man create mode 100644 hacks/glx/cubestorm.c create mode 100644 hacks/glx/cubestorm.man create mode 100644 hacks/glx/cubicgrid.c create mode 100644 hacks/glx/cubicgrid.man create mode 100644 hacks/glx/dangerball.c create mode 100644 hacks/glx/dangerball.man create mode 100644 hacks/glx/dnalogo.c create mode 100644 hacks/glx/dnapizza.h create mode 100644 hacks/glx/dolphin.c create mode 100644 hacks/glx/dropshadow.c create mode 100644 hacks/glx/dropshadow.h create mode 100755 hacks/glx/dxf2gl.pl create mode 100644 hacks/glx/e_textures.h create mode 100644 hacks/glx/endgame.c create mode 100644 hacks/glx/endgame.man create mode 100644 hacks/glx/engine.c create mode 100644 hacks/glx/engine.man create mode 100644 hacks/glx/extrusion-helix2.c create mode 100644 hacks/glx/extrusion-helix3.c create mode 100644 hacks/glx/extrusion-helix4.c create mode 100644 hacks/glx/extrusion-joinoffset.c create mode 100644 hacks/glx/extrusion-screw.c create mode 100644 hacks/glx/extrusion-taper.c create mode 100644 hacks/glx/extrusion-twistoid.c create mode 100644 hacks/glx/extrusion.c create mode 100644 hacks/glx/extrusion.h create mode 100644 hacks/glx/extrusion.man create mode 100644 hacks/glx/flipflop.c create mode 100644 hacks/glx/flipflop.man create mode 100644 hacks/glx/flipscreen3d.c create mode 100644 hacks/glx/flipscreen3d.man create mode 100644 hacks/glx/fliptext.c create mode 100644 hacks/glx/fliptext.man create mode 100644 hacks/glx/flurry-smoke.c create mode 100644 hacks/glx/flurry-spark.c create mode 100644 hacks/glx/flurry-star.c create mode 100644 hacks/glx/flurry-texture.c create mode 100644 hacks/glx/flurry.c create mode 100644 hacks/glx/flurry.h create mode 100644 hacks/glx/flurry.man create mode 100644 hacks/glx/flyingtoasters.c create mode 100644 hacks/glx/flyingtoasters.man create mode 100644 hacks/glx/font-ximage.c create mode 100644 hacks/glx/font-ximage.h create mode 100644 hacks/glx/fps-gl.c create mode 100644 hacks/glx/gears.c create mode 100644 hacks/glx/gears.man create mode 100644 hacks/glx/geodesic.c create mode 100644 hacks/glx/geodesic.man create mode 100644 hacks/glx/gflux.c create mode 100644 hacks/glx/gflux.man create mode 100644 hacks/glx/glblur.c create mode 100644 hacks/glx/glblur.man create mode 100644 hacks/glx/glcells.c create mode 100644 hacks/glx/glcells.man create mode 100644 hacks/glx/gleidescope.c create mode 100644 hacks/glx/gleidescope.man create mode 100644 hacks/glx/glforestfire.c create mode 100644 hacks/glx/glforestfire.man create mode 100644 hacks/glx/glhanoi.c create mode 100644 hacks/glx/glhanoi.man create mode 100644 hacks/glx/glknots.c create mode 100644 hacks/glx/glknots.man create mode 100644 hacks/glx/gllist.c create mode 100644 hacks/glx/gllist.h create mode 100644 hacks/glx/glmatrix.c create mode 100644 hacks/glx/glmatrix.man create mode 100644 hacks/glx/glplanet.c create mode 100644 hacks/glx/glplanet.man 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 100644 hacks/glx/glslideshow.c create mode 100644 hacks/glx/glslideshow.man create mode 100644 hacks/glx/glsnake.c create mode 100644 hacks/glx/glsnake.man create mode 100644 hacks/glx/gltext.c create mode 100644 hacks/glx/gltext.man create mode 100644 hacks/glx/gltrackball.c create mode 100644 hacks/glx/gltrackball.h create mode 100644 hacks/glx/glut_roman.h create mode 100644 hacks/glx/glut_stroke.c create mode 100644 hacks/glx/glut_swidth.c create mode 100644 hacks/glx/glutstroke.h create mode 100644 hacks/glx/glxfonts.c create mode 100644 hacks/glx/glxfonts.h create mode 100644 hacks/glx/grab-ximage.c create mode 100644 hacks/glx/grab-ximage.h create mode 100644 hacks/glx/hilbert.c create mode 100644 hacks/glx/hilbert.man create mode 100644 hacks/glx/hypertorus.c create mode 100644 hacks/glx/hypertorus.man create mode 100644 hacks/glx/hypnowheel.c create mode 100644 hacks/glx/hypnowheel.man create mode 100644 hacks/glx/involute.c create mode 100644 hacks/glx/involute.h create mode 100644 hacks/glx/jigglypuff.c create mode 100644 hacks/glx/jigglypuff.man create mode 100644 hacks/glx/jigsaw.c create mode 100644 hacks/glx/jigsaw.man create mode 100644 hacks/glx/juggler3d.c create mode 100644 hacks/glx/juggler3d.man create mode 100644 hacks/glx/jwzgles.c create mode 100644 hacks/glx/jwzgles.h create mode 100644 hacks/glx/jwzglesI.h create mode 100644 hacks/glx/kaleidocycle.c create mode 100644 hacks/glx/kaleidocycle.man create mode 100644 hacks/glx/klein.c create mode 100644 hacks/glx/klein.man create mode 100644 hacks/glx/lament.c create mode 100644 hacks/glx/lament.man create mode 100644 hacks/glx/lavalite.c create mode 100644 hacks/glx/lavalite.man create mode 100644 hacks/glx/lockward.c create mode 100644 hacks/glx/lockward.man create mode 100644 hacks/glx/marching.c create mode 100644 hacks/glx/marching.h create mode 100644 hacks/glx/menger.c create mode 100644 hacks/glx/menger.man create mode 100644 hacks/glx/mirrorblob.c create mode 100644 hacks/glx/mirrorblob.man create mode 100644 hacks/glx/moebius.c create mode 100644 hacks/glx/moebius.man create mode 100644 hacks/glx/moebiusgears.c create mode 100644 hacks/glx/moebiusgears.man create mode 100644 hacks/glx/molecule.c create mode 100644 hacks/glx/molecule.man create mode 100755 hacks/glx/molecules.sh create mode 100644 hacks/glx/morph3d.c create mode 100644 hacks/glx/morph3d.man create mode 100644 hacks/glx/noof.c create mode 100644 hacks/glx/noof.man create mode 100644 hacks/glx/normals.c create mode 100644 hacks/glx/normals.h create mode 100644 hacks/glx/photopile.c create mode 100644 hacks/glx/photopile.man create mode 100644 hacks/glx/pinion.c create mode 100644 hacks/glx/pinion.man create mode 100644 hacks/glx/pipeobjs.c create mode 100644 hacks/glx/pipes.c create mode 100644 hacks/glx/pipes.man create mode 100644 hacks/glx/polyhedra-gl.c create mode 100644 hacks/glx/polyhedra.c create mode 100644 hacks/glx/polyhedra.h create mode 100644 hacks/glx/polyhedra.man create mode 100644 hacks/glx/polytopes.c create mode 100644 hacks/glx/polytopes.man create mode 100644 hacks/glx/providence.c create mode 100644 hacks/glx/providence.man create mode 100644 hacks/glx/pulsar.c create mode 100644 hacks/glx/pulsar.man create mode 100644 hacks/glx/quasicrystal.c create mode 100644 hacks/glx/quasicrystal.man create mode 100644 hacks/glx/queens.c create mode 100644 hacks/glx/queens.man create mode 100644 hacks/glx/rotator.c create mode 100644 hacks/glx/rotator.h create mode 100644 hacks/glx/rubik.c create mode 100644 hacks/glx/rubik.man create mode 100644 hacks/glx/rubikblocks.c create mode 100644 hacks/glx/rubikblocks.man create mode 100644 hacks/glx/s1_1.c create mode 100644 hacks/glx/s1_2.c create mode 100644 hacks/glx/s1_3.c create mode 100644 hacks/glx/s1_4.c create mode 100644 hacks/glx/s1_5.c create mode 100644 hacks/glx/s1_6.c create mode 100644 hacks/glx/s1_b.c create mode 100644 hacks/glx/sballs.c create mode 100644 hacks/glx/sballs.man create mode 100644 hacks/glx/shark.c create mode 100644 hacks/glx/sierpinski3d.c create mode 100644 hacks/glx/sierpinski3d.man create mode 100644 hacks/glx/skytentacles.c create mode 100644 hacks/glx/skytentacles.man create mode 100644 hacks/glx/sonar-icmp.c create mode 100644 hacks/glx/sonar-sim.c create mode 100644 hacks/glx/sonar.c create mode 100644 hacks/glx/sonar.h create mode 100644 hacks/glx/sonar.man create mode 100644 hacks/glx/sphere.c create mode 100644 hacks/glx/sphere.h create mode 100644 hacks/glx/spheremonics.c create mode 100644 hacks/glx/spheremonics.man create mode 100644 hacks/glx/sproingies.c create mode 100644 hacks/glx/sproingies.h create mode 100644 hacks/glx/sproingies.man create mode 100644 hacks/glx/sproingiewrap.c create mode 100644 hacks/glx/stairs.c create mode 100644 hacks/glx/stairs.man create mode 100644 hacks/glx/starwars.c create mode 100644 hacks/glx/starwars.h create mode 100644 hacks/glx/starwars.man create mode 100644 hacks/glx/starwars.txt create mode 100644 hacks/glx/stonerview-move.c create mode 100644 hacks/glx/stonerview-move.h create mode 100644 hacks/glx/stonerview-osc.c create mode 100644 hacks/glx/stonerview-osc.h create mode 100644 hacks/glx/stonerview-view.c create mode 100644 hacks/glx/stonerview.c create mode 100644 hacks/glx/stonerview.h create mode 100644 hacks/glx/stonerview.man create mode 100644 hacks/glx/superquadrics.c create mode 100644 hacks/glx/superquadrics.man create mode 100644 hacks/glx/surfaces.c create mode 100644 hacks/glx/surfaces.man create mode 100644 hacks/glx/swim.c create mode 100644 hacks/glx/tangram.c create mode 100644 hacks/glx/tangram.man create mode 100644 hacks/glx/tangram_shapes.c create mode 100644 hacks/glx/tangram_shapes.h create mode 100644 hacks/glx/teapot.c create mode 100644 hacks/glx/teapot.h create mode 100644 hacks/glx/teapot2.h create mode 100644 hacks/glx/texfont.c create mode 100644 hacks/glx/texfont.h create mode 100644 hacks/glx/timetunnel.c create mode 100644 hacks/glx/timetunnel.man create mode 100644 hacks/glx/toast.c create mode 100644 hacks/glx/toast2.c create mode 100644 hacks/glx/toaster.c create mode 100644 hacks/glx/toaster_base.c create mode 100644 hacks/glx/toaster_handle.c create mode 100644 hacks/glx/toaster_handle2.c create mode 100644 hacks/glx/toaster_jet.c create mode 100644 hacks/glx/toaster_knob.c create mode 100644 hacks/glx/toaster_slots.c create mode 100644 hacks/glx/toaster_wing.c create mode 100644 hacks/glx/topblock.c create mode 100644 hacks/glx/topblock.h create mode 100644 hacks/glx/topblock.man create mode 100644 hacks/glx/trackball.c create mode 100644 hacks/glx/trackball.h create mode 100644 hacks/glx/tronbit.c create mode 100644 hacks/glx/tronbit.man create mode 100644 hacks/glx/tronbit_idle1.c create mode 100644 hacks/glx/tronbit_idle2.c create mode 100644 hacks/glx/tronbit_no.c create mode 100644 hacks/glx/tronbit_yes.c create mode 100644 hacks/glx/tube.c create mode 100644 hacks/glx/tube.h create mode 100644 hacks/glx/tunnel_draw.c create mode 100644 hacks/glx/tunnel_draw.h create mode 100644 hacks/glx/unknownpleasures.c create mode 100644 hacks/glx/unknownpleasures.man create mode 100644 hacks/glx/voronoi.c create mode 100644 hacks/glx/voronoi.man create mode 100755 hacks/glx/vrml2gl.pl create mode 100755 hacks/glx/wfront2gl.pl create mode 100644 hacks/glx/whale.c create mode 100644 hacks/glx/xlock-gl-utils.c create mode 100644 hacks/glx/xpm-ximage.c create mode 100644 hacks/glx/xpm-ximage.h create mode 100644 hacks/glx/xscreensaver-gl-helper.c create mode 100644 hacks/glx/xscreensaver-gl-helper.man create mode 100644 hacks/goop.c create mode 100644 hacks/goop.man create mode 100644 hacks/grav.c create mode 100644 hacks/grav.man create mode 100644 hacks/greynetic.c create mode 100644 hacks/greynetic.man create mode 100644 hacks/halftone.c create mode 100644 hacks/halftone.man create mode 100644 hacks/halo.c create mode 100644 hacks/halo.man create mode 100644 hacks/helix.c create mode 100644 hacks/helix.man create mode 100644 hacks/hexadrop.c create mode 100644 hacks/hexadrop.man create mode 100644 hacks/hopalong.c create mode 100644 hacks/hopalong.man create mode 100644 hacks/hyperball.c create mode 100644 hacks/hyperball.man create mode 100644 hacks/hypercube.c create mode 100644 hacks/hypercube.man create mode 100644 hacks/ifs.c create mode 100644 hacks/ifs.man create mode 100644 hacks/images/6x10font.xbm create mode 100644 hacks/images/amiga.xpm create mode 100644 hacks/images/android.xpm create mode 100644 hacks/images/apple2font.xbm create mode 100644 hacks/images/atari.xbm create mode 100644 hacks/images/atm.xbm create mode 100644 hacks/images/blocktube.xpm create mode 100644 hacks/images/bob.xbm create mode 100644 hacks/images/bubbles/blood.pov create mode 100644 hacks/images/bubbles/blood1.xpm create mode 100644 hacks/images/bubbles/blood10.xpm create mode 100644 hacks/images/bubbles/blood11.xpm create mode 100644 hacks/images/bubbles/blood2.xpm create mode 100644 hacks/images/bubbles/blood3.xpm create mode 100644 hacks/images/bubbles/blood4.xpm create mode 100644 hacks/images/bubbles/blood5.xpm create mode 100644 hacks/images/bubbles/blood6.xpm create mode 100644 hacks/images/bubbles/blood7.xpm create mode 100644 hacks/images/bubbles/blood8.xpm create mode 100644 hacks/images/bubbles/blood9.xpm create mode 100644 hacks/images/bubbles/blue.pov create mode 100644 hacks/images/bubbles/blue1.xpm create mode 100644 hacks/images/bubbles/blue10.xpm create mode 100644 hacks/images/bubbles/blue11.xpm create mode 100644 hacks/images/bubbles/blue2.xpm create mode 100644 hacks/images/bubbles/blue3.xpm create mode 100644 hacks/images/bubbles/blue4.xpm create mode 100644 hacks/images/bubbles/blue5.xpm create mode 100644 hacks/images/bubbles/blue6.xpm create mode 100644 hacks/images/bubbles/blue7.xpm create mode 100644 hacks/images/bubbles/blue8.xpm create mode 100644 hacks/images/bubbles/blue9.xpm create mode 100644 hacks/images/bubbles/glass.pov create mode 100644 hacks/images/bubbles/glass1.xpm create mode 100644 hacks/images/bubbles/glass10.xpm create mode 100644 hacks/images/bubbles/glass11.xpm create mode 100644 hacks/images/bubbles/glass2.xpm create mode 100644 hacks/images/bubbles/glass3.xpm create mode 100644 hacks/images/bubbles/glass4.xpm create mode 100644 hacks/images/bubbles/glass5.xpm create mode 100644 hacks/images/bubbles/glass6.xpm create mode 100644 hacks/images/bubbles/glass7.xpm create mode 100644 hacks/images/bubbles/glass8.xpm create mode 100644 hacks/images/bubbles/glass9.xpm create mode 100644 hacks/images/bubbles/jade.pov create mode 100644 hacks/images/bubbles/jade1.xpm create mode 100644 hacks/images/bubbles/jade10.xpm create mode 100644 hacks/images/bubbles/jade11.xpm create mode 100644 hacks/images/bubbles/jade2.xpm create mode 100644 hacks/images/bubbles/jade3.xpm create mode 100644 hacks/images/bubbles/jade4.xpm create mode 100644 hacks/images/bubbles/jade5.xpm create mode 100644 hacks/images/bubbles/jade6.xpm create mode 100644 hacks/images/bubbles/jade7.xpm create mode 100644 hacks/images/bubbles/jade8.xpm create mode 100644 hacks/images/bubbles/jade9.xpm create mode 100644 hacks/images/chromesphere.xpm create mode 100644 hacks/images/earth.xpm create mode 100644 hacks/images/ground.xpm create mode 100644 hacks/images/hmac.xpm create mode 100644 hacks/images/jigglymap.xpm create mode 100644 hacks/images/lament128.xpm create mode 100644 hacks/images/lament512.xpm create mode 100644 hacks/images/m6502/amiga.asm create mode 100644 hacks/images/m6502/breakout.asm create mode 100644 hacks/images/m6502/byterun.asm create mode 100644 hacks/images/m6502/cellular-30.asm create mode 100644 hacks/images/m6502/cellular-600.asm create mode 100644 hacks/images/m6502/colors.asm create mode 100644 hacks/images/m6502/crunch6502.asm create mode 100644 hacks/images/m6502/demoscene.asm create mode 100644 hacks/images/m6502/disco.asm create mode 100644 hacks/images/m6502/dmsc.asm create mode 100644 hacks/images/m6502/dragon-fractal.asm create mode 100644 hacks/images/m6502/fullscreenlogo.asm create mode 100644 hacks/images/m6502/keftal.asm create mode 100644 hacks/images/m6502/matrix.asm create mode 100644 hacks/images/m6502/noise.asm create mode 100644 hacks/images/m6502/random-walk.asm create mode 100644 hacks/images/m6502/random.asm create mode 100644 hacks/images/m6502/random2.asm create mode 100644 hacks/images/m6502/rorschach.asm create mode 100644 hacks/images/m6502/santa.asm create mode 100644 hacks/images/m6502/selfmodify.asm create mode 100644 hacks/images/m6502/sierpinsky.asm create mode 100644 hacks/images/m6502/softsprite.asm create mode 100644 hacks/images/m6502/spacer.asm create mode 100644 hacks/images/m6502/starfield2d.asm create mode 100644 hacks/images/m6502/wave6502.asm create mode 100644 hacks/images/m6502/zookeeper.asm create mode 100644 hacks/images/mac.xbm create mode 100644 hacks/images/macbomb.xbm create mode 100644 hacks/images/matrix1.xbm create mode 100644 hacks/images/matrix1.xpm create mode 100644 hacks/images/matrix1b.xbm create mode 100644 hacks/images/matrix1b.xpm create mode 100644 hacks/images/matrix2.xbm create mode 100644 hacks/images/matrix2.xpm create mode 100644 hacks/images/matrix2b.xbm create mode 100644 hacks/images/matrix2b.xpm create mode 100644 hacks/images/matrix3.xpm create mode 100644 hacks/images/molecules/adenine.pdb create mode 100644 hacks/images/molecules/adrenochrome.pdb create mode 100644 hacks/images/molecules/bucky.pdb create mode 100644 hacks/images/molecules/caffeine.pdb create mode 100644 hacks/images/molecules/capsaicin.pdb create mode 100644 hacks/images/molecules/chlordecone.pdb create mode 100644 hacks/images/molecules/cocaine.pdb create mode 100644 hacks/images/molecules/codeine.pdb create mode 100644 hacks/images/molecules/cyclohexane.pdb create mode 100644 hacks/images/molecules/cytosine.pdb create mode 100644 hacks/images/molecules/dna.pdb create mode 100644 hacks/images/molecules/dodecahedrane.pdb create mode 100644 hacks/images/molecules/dthc.pdb create mode 100644 hacks/images/molecules/dynamite.pdb create mode 100644 hacks/images/molecules/glycol.pdb create mode 100644 hacks/images/molecules/guanine.pdb create mode 100644 hacks/images/molecules/heroin.pdb create mode 100644 hacks/images/molecules/hexahelicene.pdb create mode 100644 hacks/images/molecules/ibuprofen.pdb create mode 100644 hacks/images/molecules/lsd.pdb create mode 100644 hacks/images/molecules/menthol.pdb create mode 100644 hacks/images/molecules/mescaline.pdb create mode 100644 hacks/images/molecules/methamphetamine.pdb create mode 100644 hacks/images/molecules/morphine.pdb create mode 100644 hacks/images/molecules/nicotine.pdb create mode 100644 hacks/images/molecules/novocaine.pdb create mode 100644 hacks/images/molecules/olestra.pdb create mode 100644 hacks/images/molecules/penicillin.pdb create mode 100644 hacks/images/molecules/salvinorin.pdb create mode 100644 hacks/images/molecules/sarin.pdb create mode 100644 hacks/images/molecules/strychnine.pdb create mode 100644 hacks/images/molecules/sucrose.pdb create mode 100644 hacks/images/molecules/thalidomide.pdb create mode 100644 hacks/images/molecules/thymine.pdb create mode 100644 hacks/images/molecules/viagra.pdb create mode 100644 hacks/images/molecules/vitaminb6.pdb create mode 100644 hacks/images/molecules/vitaminc.pdb create mode 100644 hacks/images/molecules/vx.pdb create mode 100644 hacks/images/noseguy/nose-f1.xbm create mode 100644 hacks/images/noseguy/nose-f1.xpm create mode 100644 hacks/images/noseguy/nose-f2.xbm create mode 100644 hacks/images/noseguy/nose-f2.xpm create mode 100644 hacks/images/noseguy/nose-f3.xbm create mode 100644 hacks/images/noseguy/nose-f3.xpm create mode 100644 hacks/images/noseguy/nose-f4.xbm create mode 100644 hacks/images/noseguy/nose-f4.xpm create mode 100644 hacks/images/noseguy/nose-l1.xbm create mode 100644 hacks/images/noseguy/nose-l1.xpm create mode 100644 hacks/images/noseguy/nose-l2.xbm create mode 100644 hacks/images/noseguy/nose-l2.xpm create mode 100644 hacks/images/noseguy/nose-r1.xbm create mode 100644 hacks/images/noseguy/nose-r1.xpm create mode 100644 hacks/images/noseguy/nose-r2.xbm create mode 100644 hacks/images/noseguy/nose-r2.xpm create mode 100644 hacks/images/osx_10_2.xpm create mode 100644 hacks/images/osx_10_3.xpm create mode 100644 hacks/images/pacman/eyes-d.xpm create mode 100644 hacks/images/pacman/eyes-l.xpm create mode 100644 hacks/images/pacman/eyes-r.xpm create mode 100644 hacks/images/pacman/eyes-u.xpm create mode 100644 hacks/images/pacman/ghost-d1.xpm create mode 100644 hacks/images/pacman/ghost-d2.xpm create mode 100644 hacks/images/pacman/ghost-l1.xpm create mode 100644 hacks/images/pacman/ghost-l2.xpm create mode 100644 hacks/images/pacman/ghost-mask.xpm create mode 100644 hacks/images/pacman/ghost-r1.xpm create mode 100644 hacks/images/pacman/ghost-r2.xpm create mode 100644 hacks/images/pacman/ghost-s1.xpm create mode 100644 hacks/images/pacman/ghost-s2.xpm create mode 100644 hacks/images/pacman/ghost-sf1.xpm create mode 100644 hacks/images/pacman/ghost-sf2.xpm create mode 100644 hacks/images/pacman/ghost-u1.xpm create mode 100644 hacks/images/pacman/ghost-u2.xpm create mode 100644 hacks/images/pacman/pacman-0.xpm create mode 100644 hacks/images/pacman/pacman-d1.xpm create mode 100644 hacks/images/pacman/pacman-d2.xpm create mode 100644 hacks/images/pacman/pacman-ds1.xpm create mode 100644 hacks/images/pacman/pacman-ds2.xpm create mode 100644 hacks/images/pacman/pacman-ds3.xpm create mode 100644 hacks/images/pacman/pacman-ds4.xpm create mode 100644 hacks/images/pacman/pacman-ds5.xpm create mode 100644 hacks/images/pacman/pacman-ds6.xpm create mode 100644 hacks/images/pacman/pacman-ds7.xpm create mode 100644 hacks/images/pacman/pacman-ds8.xpm create mode 100644 hacks/images/pacman/pacman-l1.xpm create mode 100644 hacks/images/pacman/pacman-l2.xpm create mode 100644 hacks/images/pacman/pacman-r1.xpm create mode 100644 hacks/images/pacman/pacman-r2.xpm create mode 100644 hacks/images/pacman/pacman-u1.xpm create mode 100644 hacks/images/pacman/pacman-u2.xpm create mode 100644 hacks/images/sball-bg.xpm create mode 100644 hacks/images/sball.xpm create mode 100644 hacks/images/scales.xpm create mode 100644 hacks/images/sea-texture.xpm create mode 100644 hacks/images/som.xbm create mode 100644 hacks/images/timetunnel0.xpm create mode 100644 hacks/images/timetunnel1.xpm create mode 100644 hacks/images/timetunnel2.xpm create mode 100644 hacks/images/toast.xpm create mode 100644 hacks/images/tree.xpm create mode 100644 hacks/images/tunnel0.xpm create mode 100644 hacks/images/tunnel1.xpm create mode 100644 hacks/images/tunnel2.xpm create mode 100644 hacks/images/tunnel3.xpm create mode 100644 hacks/images/tunnel4.xpm create mode 100644 hacks/images/tunnel5.xpm create mode 100644 hacks/images/tunnelstar.xpm create mode 100644 hacks/images/wood.xpm create mode 100644 hacks/imsmap.c create mode 100644 hacks/imsmap.man create mode 100644 hacks/interaggregate.c create mode 100644 hacks/interaggregate.man create mode 100644 hacks/interference.c create mode 100644 hacks/interference.man create mode 100644 hacks/intermomentary.c create mode 100644 hacks/intermomentary.man create mode 100644 hacks/juggle.c create mode 100644 hacks/juggle.man create mode 100644 hacks/julia.c create mode 100644 hacks/julia.man create mode 100644 hacks/kaleidescope.c create mode 100644 hacks/kaleidescope.man create mode 100644 hacks/kumppa.c create mode 100644 hacks/kumppa.man create mode 100644 hacks/laser.c create mode 100644 hacks/laser.man create mode 100644 hacks/lcdscrub.c create mode 100644 hacks/lcdscrub.man create mode 100644 hacks/lightning.c create mode 100644 hacks/lightning.man create mode 100644 hacks/link_axp.com create mode 100644 hacks/link_decc.com create mode 100644 hacks/lisa.c create mode 100644 hacks/lisa.man create mode 100644 hacks/lissie.c create mode 100644 hacks/lissie.man create mode 100755 hacks/ljlatest create mode 100644 hacks/ljlatest.man create mode 100644 hacks/lmorph.c create mode 100644 hacks/lmorph.man create mode 100644 hacks/loop.c create mode 100644 hacks/loop.man create mode 100644 hacks/m6502.c create mode 100755 hacks/m6502.sh create mode 100644 hacks/maze.c create mode 100644 hacks/maze.man create mode 100644 hacks/memscroller.c create mode 100644 hacks/memscroller.man create mode 100644 hacks/metaballs.c create mode 100644 hacks/metaballs.man create mode 100644 hacks/moire.c create mode 100644 hacks/moire.man create mode 100644 hacks/moire2.c create mode 100644 hacks/moire2.man create mode 100644 hacks/mountain.c create mode 100644 hacks/mountain.man create mode 100644 hacks/munch.c create mode 100644 hacks/munch.man create mode 100755 hacks/munge-ad.pl create mode 100644 hacks/nerverot.c create mode 100644 hacks/nerverot.man create mode 100644 hacks/noseguy.c create mode 100644 hacks/noseguy.man create mode 100644 hacks/pacman.c create mode 100644 hacks/pacman.h create mode 100644 hacks/pacman.man create mode 100644 hacks/pacman_ai.c create mode 100644 hacks/pacman_ai.h create mode 100644 hacks/pacman_level.c create mode 100644 hacks/pacman_level.h create mode 100644 hacks/pedal.c create mode 100644 hacks/pedal.man create mode 100644 hacks/penetrate.c create mode 100644 hacks/penetrate.man create mode 100644 hacks/penrose.c create mode 100644 hacks/penrose.man create mode 100644 hacks/petri.c create mode 100644 hacks/petri.man create mode 100644 hacks/phosphor.c create mode 100644 hacks/phosphor.man create mode 100644 hacks/piecewise.c create mode 100644 hacks/piecewise.man create mode 100644 hacks/polyominoes.c create mode 100644 hacks/polyominoes.man create mode 100644 hacks/pong.c create mode 100644 hacks/pong.man create mode 100644 hacks/popsquares.c create mode 100644 hacks/pyro.c create mode 100644 hacks/pyro.man create mode 100644 hacks/qix.c create mode 100644 hacks/qix.man create mode 100644 hacks/rd-bomb.c create mode 100644 hacks/rd-bomb.man create mode 100644 hacks/ripples.c create mode 100644 hacks/ripples.man create mode 100644 hacks/rocks.c create mode 100644 hacks/rocks.man create mode 100644 hacks/rorschach.c create mode 100644 hacks/rorschach.man create mode 100644 hacks/rotor.c create mode 100644 hacks/rotor.man create mode 100644 hacks/rotzoomer.c create mode 100644 hacks/rotzoomer.man create mode 100644 hacks/screenhack.c create mode 100644 hacks/screenhack.h create mode 100644 hacks/screenhackI.h create mode 100644 hacks/shadebobs.c create mode 100644 hacks/shadebobs.man create mode 100644 hacks/sierpinski.c create mode 100644 hacks/sierpinski.man create mode 100644 hacks/slidescreen.c create mode 100644 hacks/slidescreen.man create mode 100644 hacks/slip.c create mode 100644 hacks/slip.man create mode 100644 hacks/speedmine.c create mode 100644 hacks/speedmine.man create mode 100644 hacks/sphere.c create mode 100644 hacks/sphere.man create mode 100644 hacks/spiral.c create mode 100644 hacks/spiral.man create mode 100644 hacks/spotlight.c create mode 100644 hacks/spotlight.man create mode 100644 hacks/squiral.c create mode 100644 hacks/squiral.man create mode 100644 hacks/starfish.c create mode 100644 hacks/starfish.man create mode 100644 hacks/strange.c create mode 100644 hacks/strange.man create mode 100644 hacks/substrate.c create mode 100644 hacks/substrate.man create mode 100644 hacks/swirl.c create mode 100644 hacks/swirl.man create mode 100644 hacks/t3d.c create mode 100644 hacks/t3d.man create mode 100644 hacks/thornbird.c create mode 100644 hacks/thornbird.man create mode 100644 hacks/triangle.c create mode 100644 hacks/triangle.man create mode 100644 hacks/truchet.c create mode 100644 hacks/truchet.man create mode 100644 hacks/twang.c create mode 100644 hacks/twang.man create mode 100644 hacks/vermiculate.c create mode 100644 hacks/vermiculate.man create mode 100755 hacks/vidwhacker create mode 100644 hacks/vidwhacker.man create mode 100644 hacks/vines.c create mode 100644 hacks/vines.man create mode 100644 hacks/vms_axp.opt create mode 100644 hacks/vms_axp_12.opt create mode 100644 hacks/vms_decc.opt create mode 100644 hacks/vms_decc_12.opt create mode 100644 hacks/wander.c create mode 100644 hacks/wander.man create mode 100755 hacks/webcollage create mode 100644 hacks/webcollage-cocoa.m create mode 100644 hacks/webcollage-helper-cocoa.m create mode 100644 hacks/webcollage-helper.c create mode 100644 hacks/webcollage.man create mode 100644 hacks/whirlwindwarp.c create mode 100644 hacks/whirlwindwarp.man create mode 100644 hacks/whirlygig.c create mode 100644 hacks/whirlygig.man create mode 100644 hacks/worm.c create mode 100644 hacks/worm.man create mode 100644 hacks/wormhole.c create mode 100644 hacks/wormhole.man create mode 100644 hacks/xanalogtv.c create mode 100644 hacks/xanalogtv.man create mode 100644 hacks/xflame.c create mode 100644 hacks/xflame.man create mode 100644 hacks/xjack.c create mode 100644 hacks/xjack.man create mode 100644 hacks/xlockmore.c create mode 100644 hacks/xlockmore.h create mode 100644 hacks/xlockmoreI.h create mode 100644 hacks/xlyap.c create mode 100644 hacks/xlyap.man create mode 100644 hacks/xmatrix.c create mode 100644 hacks/xmatrix.man create mode 100755 hacks/xml2man.pl create mode 100644 hacks/xpm-pixmap.c create mode 100644 hacks/xpm-pixmap.h create mode 100644 hacks/xrayswarm.c create mode 100644 hacks/xrayswarm.man create mode 100644 hacks/xscreensaver-sgigl.c create mode 100644 hacks/xspirograph.c create mode 100644 hacks/xspirograph.man create mode 100644 hacks/xsublim.c create mode 100644 hacks/xsublim.man create mode 100644 hacks/zoom.c create mode 100644 hacks/zoom.man create mode 100644 install-sh create mode 100644 intltool-extract.in create mode 100644 intltool-merge.in create mode 100644 intltool-update.in create mode 100644 makevms.com create mode 100644 po/ChangeLog create mode 100644 po/Makefile.in.in create mode 100644 po/POTFILES.in create mode 100644 po/ca.po create mode 100644 po/da.po create mode 100644 po/de.po create mode 100644 po/es.po create mode 100644 po/et.po create mode 100644 po/fi.po create mode 100644 po/fr.po create mode 100644 po/hu.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100644 po/ko.po create mode 100644 po/nb.po create mode 100644 po/nl.po create mode 100644 po/pl.po create mode 100644 po/pt.po create mode 100644 po/pt_BR.po create mode 100644 po/ru.po create mode 100644 po/sk.po create mode 100644 po/sv.po create mode 100755 po/update.sh create mode 100644 po/vi.po create mode 100644 po/wa.po create mode 100644 po/zh_CN.po create mode 100644 po/zh_TW.po create mode 100644 setup.com create mode 100644 utils/Makefile.in create mode 100644 utils/README create mode 100755 utils/ad2c create mode 100644 utils/alpha.c create mode 100644 utils/alpha.h create mode 100644 utils/colorbars.c create mode 100644 utils/colorbars.h create mode 100644 utils/colors.c create mode 100644 utils/colors.h create mode 100644 utils/compile_axp.com create mode 100644 utils/compile_decc.com create mode 100644 utils/erase.c create mode 100644 utils/erase.h create mode 100644 utils/fade.c create mode 100644 utils/fade.h create mode 100644 utils/grabclient.c create mode 100644 utils/grabscreen.c create mode 100644 utils/grabscreen.h create mode 100644 utils/hsv.c create mode 100644 utils/hsv.h create mode 100644 utils/images/logo-180.gif create mode 100644 utils/images/logo-180.xpm create mode 100644 utils/images/logo-50.gif create mode 100644 utils/images/logo-50.xpm create mode 100644 utils/images/logo-big.gif create mode 100644 utils/images/logo.eps create mode 100644 utils/images/screensaver-cmndln.png create mode 100644 utils/images/screensaver-colorselector.png create mode 100644 utils/images/screensaver-diagnostic.png create mode 100644 utils/images/screensaver-locking.png create mode 100644 utils/images/screensaver-power.png create mode 100644 utils/images/screensaver-snap.png create mode 100644 utils/logo.c create mode 100644 utils/minixpm.c create mode 100644 utils/minixpm.h create mode 100644 utils/overlay.c create mode 100644 utils/resources.c create mode 100644 utils/resources.h create mode 100644 utils/spline.c create mode 100644 utils/spline.h create mode 100644 utils/textclient.c create mode 100644 utils/textclient.h create mode 100644 utils/usleep.c create mode 100644 utils/usleep.h create mode 100644 utils/utils.h create mode 100644 utils/version.h create mode 100644 utils/visual-gl.c create mode 100644 utils/visual.c create mode 100644 utils/visual.h create mode 100644 utils/vms-gtod.c create mode 100644 utils/vms-gtod.h create mode 100644 utils/vms-strdup.c create mode 100644 utils/vroot.h create mode 100644 utils/xdbe.c create mode 100644 utils/xdbe.h create mode 100644 utils/xmu.c create mode 100644 utils/xmu.h create mode 100644 utils/xscreensaver-intl.h create mode 100644 utils/xshm.c create mode 100644 utils/xshm.h create mode 100644 utils/yarandom.c create mode 100644 utils/yarandom.h create mode 100644 xscreensaver.spec create mode 100644 xscreensaver.xcodeproj/project.pbxproj diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..50dbe439 --- /dev/null +++ b/INSTALL @@ -0,0 +1,183 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..aa233b8a --- /dev/null +++ b/Makefile.in @@ -0,0 +1,370 @@ +# Makefile.in --- xscreensaver, Copyright (c) 1999-2010 Jamie Zawinski. +# the `../configure' script generates `Makefile' from this file. + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +SHELL = /bin/sh +SUBDIRS = utils driver hacks hacks/glx po +#SUBDIRS = utils driver hacks hacks/glx +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 $(MAKE) -C $$dir $@ || exit 5; done +MAKE_SUBDIR2 = for dir in $(SUBDIRS2); do $(MAKE) -C $$dir $@ || exit 5; done + +default:: + @$(MAKE_SUBDIR) +all:: + @$(MAKE_SUBDIR) +install:: + @$(MAKE_SUBDIR) +install-program:: + @$(MAKE_SUBDIR) +install-man:: + @$(MAKE_SUBDIR) +install-strip:: + @$(MAKE_SUBDIR) +uninstall:: + @$(MAKE_SUBDIR) +uninstall-program:: + @$(MAKE_SUBDIR) +uninstall-man:: + @$(MAKE_SUBDIR) +depend:: + @$(MAKE_SUBDIR) +distdepend:: + @$(MAKE) update_spec_version + @$(MAKE_SUBDIR2) + @$(MAKE) -C po update-po + +TAGS:: tags +tags:: + @$(MAKE_SUBDIR) + +clean:: + @$(MAKE_SUBDIR2) + +distclean:: clean + -rm -f config.h Makefile config.status config.cache config.log TAGS *~ "#"* intltool-extract intltool-merge intltool-update + @$(MAKE_SUBDIR2) + +dist:: tar + +# This really makes me sick... +tar:: + @ \ + sh config.status ; \ + rm -f configure ; \ + $(MAKE) configure ; \ + $(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 $(SUBDIRS2) ; do \ + d=`pwd` ; \ + cd $$subdir ; \ + FILES="$$FILES `$(MAKE) echo_tarfiles \ + | grep -v '^.*make\[' \ + | sed \"s|^|$$subdir/|g;s| | $$subdir/|g\" \ + ` "; \ + cd $$d ; done ; \ + echo creating tar file $$ADIR$$NAME.tar.gz... ; \ + export COPYFILE_DISABLE=true ; \ + GZIP="-9v" $(TAR) -vczf $$ADIR$$NAME.tar.gz \ + `echo $(TARFILES) $$FILES | sed "s|^|$$NAME/|g; s| | $$NAME/|g" ` ; \ + rm $$NAME + + +# This also makes me sick... +# autoconf generates a configure script that begins with a very hard to read, +# nearly impossible to customize --help blurb. This horrid set of regexps +# go through and clean up the help text, by inserting whitespace and ripping +# out options we don't use. Odds are good that this will fail with any version +# of autoconf other than the ones I've tried (2.12 and 2.13.) +# +configure:: + autoconf + autoheader + @TMP=configure.$$$$ ; \ + echo "munging configure's --help message..." ; \ + ( perl -e ' \ + my $$file=""; \ + while (<>) { $$file .= $$_; } \ + $$_ = $$file; \ + \ + s/^(Configuration:)$$/\n$$1\n/m; \ + s/^(Directory and file names:)$$/\n$$1\n/m; \ + s/^ --sbindir=.*\n//m; \ + s/^ --sysconfdir.*\n//m; \ + s/^ --sharedstatedir.*\n.*\n//m; \ + s/^ --localstatedir.*\n//m; \ + s/^ --infodir.*\n//m; \ + s/^(Host type:)$$/\n$$1\n/m; \ + s/\nFeatures and packages:\n.*library files are in DIR\n/\n/s;\ + s/--enable and --with options recognized://m; \ + s/\n --with-x .*?(["\n])/$$1/s; \ + s/\n(Installation options:\n)/$$1/s; \ + \ + s/^ --oldincludedir=.*$$/ \ + --x-includes=DIR X include files are in DIR\n \ + --x-libraries=DIR X library files are in DIR/m; \ + \ + s@mandir=.\$${prefix}/man.@mandir=\\\$${datadir}/man@; \ + \ + s@rm -f conftest@rm -rf conftest@g; \ + \ + print;' \ + < configure \ + > $$TMP && \ + cat $$TMP > configure ) ; \ + rm -f $$TMP + +bump-version:: + @ \ + SRC=utils/version.h ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\)\.\([0-9][^. ]*\).*/\1 \2/p' $$SRC` ; \ + set - $$VERS ; \ + MAJOR="$$1"; MINOR="$$2"; \ + NEW=`echo $$MINOR + 1 | bc` ; \ + NEW=`echo $$NEW | sed 's/^\([0-9]\)$$/0\1/'` ; \ + D=`date '+%d-%b-%Y'`; \ + ADIR=archive/ ; \ + if [ ! -f $${ADIR}xscreensaver-$$MAJOR.$$MINOR.tar.gz ]; then \ + echo "WARNING: $${ADIR}xscreensaver-$$MAJOR.$$MINOR.tar.gz does not exist.";\ + fi ; \ + if [ -f $${ADIR}xscreensaver-$$MAJOR.$$NEW.tar.gz ]; then \ + echo "WARNING: $${ADIR}xscreensaver-$$MAJOR.$$NEW.tar.gz already exists.";\ + fi ; \ + /bin/echo -n "Bumping $$MAJOR.$$MINOR to $$MAJOR.$$NEW ($$D), ok? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + TMP=/tmp/bv.$$ ; \ + sed -e "s/\([0-9]\.[0-9][0-9]*\)/$$MAJOR.$$NEW/" \ + -e "s/\(([0-9][0-9]*-[A-Za-z][a-z][a-z]-[0-9][0-9][0-9]*\))/($$D)/" \ + $$SRC > $$TMP ; \ + /bin/echo -n "New version and date are "; \ + sed -n "s/[^0-9]*\([0-9]\.[0-9][0-9]*\) (\([-A-Za-z0-9]*\)).*/\1, \2./p" \ + $$TMP; \ + cat $$TMP > $$SRC ; \ + rm -f $$TMP; \ + echo "overwrote $$SRC"; \ + ls -lFd $$SRC + +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 ; \ + /bin/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 ; \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' < $$U` ; \ + /bin/echo -n "Updating $$S to \"$$VERS\"... " ; \ + T=/tmp/xs.$$$$ ; \ + sed "s/^\(%define.version[^0-9]*\)\(.*\)/\1$$VERS/" \ + < $$S > $$T ; \ + if cmp -s $$S $$T ; then \ + echo "unchanged." ; \ + else \ + cat $$T > $$S ; \ + echo "done." ; \ + fi ; \ + rm $$T + +rpm:: + @ \ + VERS=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' utils/version.h` ; \ + DIR=`pwd`/rpm_build ; \ + ARCH=`rpm --showrc | sed -n 's/^build arch *: //p'` ; \ + ADIR=archive/ ; \ + TGZ=xscreensaver-$$VERS.tar.gz ; \ + if [ ! -f $${ADIR}$$TGZ ]; then \ + echo "$${ADIR}$$TGZ does not exist! Did you forget to \`make tar'?" ; \ + exit 1 ; \ + fi ; \ + rm -rf /var/tmp/xscreensaver-$$VERS-root ; \ + rm -rf $$DIR ; \ + mkdir $$DIR ; \ + ( cd $$DIR; mkdir BUILD RPMS RPMS/$$ARCH SOURCES SPECS SRPMS ) ; \ + cp -p $${ADIR}$$TGZ $$DIR/SOURCES/ ; \ + rpmbuild --define "_topdir $$DIR" \ + --define "USE_GL yes" \ + -v -ba xscreensaver.spec ; \ + echo '' ; \ + echo 'RPM build complete' ; \ + echo '' ; \ + rm -f $$DIR/$$TGZ ; \ + rm -rf $$DIR/BUILD/xscreensaver-$$VERS ; \ + mv $$DIR/SRPMS/xscreensaver*-$$VERS-*.rpm . ; \ + mv $$DIR/RPMS/$$ARCH/xscreensaver*-$$VERS-*.rpm . ; \ + rm -rf $$DIR ; \ + echo '' ; \ + ls -lFG xscreensaver*-$$VERS-*.rpm + +test-tar:: + @ \ + 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" ; \ + if [ ! -f $$NAME ]; then \ + echo "$$NAME does not exist! Did you forget to \`make tar'?" ; \ + exit 1 ; \ + fi ; \ + \ + set -e ; \ + set -x ; \ + \ + if [ -d $$D ]; then \ + chmod -R u+w $$D ; \ + fi ; \ + rm -rf $$D ; \ + zcat $${ADIR}$$D.tar.gz | tar -xf - ; \ + cd $$D ; \ + chmod -R a-w . ; \ + chmod u+w . ; \ + mkdir BIN ; \ + mkdir BIN/motif ; \ + mkdir BIN/lesstif ; \ + chmod a-w . ; \ + \ + ( cd BIN/motif ; \ + CC=cc ; \ + export CC ; \ + ../../configure --without-xpm --without-xdbe --without-xshm \ + --with-motif=/usr/local/motif ; \ + echo --------------------------------------------------------------- ; \ + gmake all ; \ + ( cd driver; gmake tests ) ; \ + echo --------------------------------------------------------------- ); \ + \ + ( cd BIN/lesstif ; \ + CC=cc ; \ + export CC ; \ + ../../configure --with-motif=/usr/local/lesstif --without-gnome ; \ + echo --------------------------------------------------------------- ; \ + ( cd utils; gmake all ) ; \ + ( cd driver; gmake all ) ; \ + echo --------------------------------------------------------------- ); \ + \ + chmod -R u+w . + +dmg:: + $(MAKE) -C OSX release dmg + +www:: + @ \ + DEST=$$HOME/www/xscreensaver ; \ + 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 \ + /bin/echo -n "WARNING: $$DNAME already exists! Overwrite? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + fi ; \ + if [ -f $$DNAME2 ]; then \ + /bin/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 ; \ + cp -p $$NAME2 $$DNAME2 ; \ + chmod u+w $$DNAME $$DNAME2 ; \ + cd $$DEST ; \ + \ + TMP=/tmp/xd.$$$$ ; \ + sed "s/xscreensaver-5\.[0-9][0-9ab]*/$$HEAD/g" download.html > $$TMP ; \ + echo '' ; \ + diff -U0 download.html $$TMP ; \ + echo '' ; \ + \ + for EXT in tar.gz dmg ; do \ + OLDEST=`ls xscreensaver*.$$EXT | \ + fgrep -v 5.14 | \ + head -n 1` ; \ + /bin/echo -n "Delete $$DEST/$$OLDEST? "; \ + read line; \ + if [ "x$$line" = "xyes" -o "x$$line" = "xy" ]; then \ + set -x ; \ + rm $$OLDEST ; \ + cvs remove $$OLDEST ; \ + set +x ; \ + fi ; \ + done ; \ + set -x ; \ + cvs add -kb $$BNAME $$BNAME2 ; \ + cat $$TMP > download.html ; \ + rm -f $$TMP ; \ + \ + $(MAKE) -C ../ xscreensaver/changelog.html xscreensaver/screenshots/index.html; \ + cvs diff -U0 changelog.html ; \ + set +x ; \ + \ + /bin/echo -n "Ok? "; \ + read line; \ + if [ "x$$line" != "xyes" -a "x$$line" != "xy" ]; then \ + exit 1 ; \ + fi ; \ + \ + cvs commit -m "$$VERS" + + +count:: + @ \ + /bin/echo -n "Current hack count: " ; \ + ( ( cd hacks; make -s INSTALL=true install-program install-scripts ) ; \ + ( cd hacks/glx; make -s INSTALL=true install-program ) ) | \ + grep true | \ + grep -v helper | \ + grep -v ljlatest | \ + wc -l diff --git a/OSX/Default-568h@2x.png b/OSX/Default-568h@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0891b7aabfcf3422423b109c8beed2bab838c607 GIT binary patch literal 18594 zcmeI4X;f257Jx&9fS`ixvS;&$x8J@slQFSel)6zJN=?13FB7H(lQjRkSy8x_-S~tvu2gzn1oS+dLcF#eqtq$ z%tf9TTvX?`)R@}3uBI;jzS-=ZR-Td&MHaS&;!0?Ni*#$#`n*~CcQK)Q9vAQ~TUpnI!j)a2biYK^R)M~A5wUDZhx?ULMX z3x1P&qt=trOY6P2U67L=m=U?F|5#Uj(eCueNTZaHs_ceWiHeET+j+tp3Jt9g(ekqP z2WOvfR{qV+9r+o4J5?qK>7;;^+I7tGv-i)es$X_D=EoKF+S?zsyj^oRFElP}c}JT< zd8SUs-?O?}2YD#ngKbnHgzHBcboxK_2r9l(?eNCl-pEzkJm}fY?WC*jnS?VBE4EpY zO$fEejz6fU;W2Kl>JeQBZBl-%Irg`obSlg*@4QB;Dd1H7^Oi5wvt4d{RZ!8Og?^aE z)k0$1g+V3fd(gdQ3d&q2q-FL*uy#}|bc^=VhFsl0jBgUGJ+-s3U8MK9A!YJJMxpci z5hJ%|{DwV48fZn0{n5l$N_KcSb#NKE4plB`9I6Zt=Z!~-zw0{9tg$L&Ju1F0X)Cy8 zKF;(&lJ>x)Jw(=;p~sF(Sd9VWGwFE2rnyS9!f^DZ8+aCLq zQ};>lcJ1GDLqjm6Hd>|Eabno@P`~Bn(~6^aD_#yoEH(a?Nm1S<;S+hSxI5d16^<1lEM3NPFi zkqPrpL)+ zgnseFikg`gJVBha1&7C4;O6>h=dt~`ND+;Zd?W(4v2JIb7Pt>Td42%M-Ju-XAH#Pns762L}K3 zDhvsRqN0Ni(1UrishD2YvV?4*h2iFj$+&N||Fn$4n|^NSU+o?~jq`0jVQt8T9l{7b zXiwwODFh2V!Q6sqP9S>WH$oOf$N~=d0-bqTlD61!=`&0eAP-F>XN?*|gtOXX{ zQVTWyYo4ZK0GAw!GHf|pz9`D;-bbb*5LBX*{bnz|+)$@&P9|ORM2o?95{;ejvo&r- zq8cBhTN6nn)7~W>54U)%-F_-b?YKdfk5I8MHcuzBD5)!;yv#Z&R&^y=@=>VTIMy#r zX&U<=BsPkdqcMe<_}2+>H%XKyrr5ZR8_KVe>ZqYN z^=^~TFD};;rHJ$U;{~w^hYojl4hRI@SH$^K{YEo=sg)WY87r!*7blQK&qnpDo0`Vn zkl)9u9g=mCh&ZCJS(L4yN3k0kQ zuvg$h2KEEk51T+O0JQ+r0`R>g{jvqM0Mr6d3qUOZwE!?PI7HY@CE|dr sfw?Q;rAv?G4&^^8-z_>&sWXMxvD*gPOU4CBe-*@OtE+wfmVJNyHv)PfH~;_u literal 0 HcmV?d00001 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/SaverRunner.nib/designable.nib b/OSX/English.lproj/SaverRunner.nib/designable.nib new file mode 100644 index 00000000..1facee5e --- /dev/null +++ b/OSX/English.lproj/SaverRunner.nib/designable.nib @@ -0,0 +1,1790 @@ + + + + 1050 + 10K549 + 851 + 1038.36 + 461.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 851 + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + + NSApplication + + + + FirstResponder + + + NSApplication + + + MainMenu + + + + XScreenSaver + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + XScreenSaver + + + + About XScreenSaver + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + YES + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + + Services + + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide XScreenSaver + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit XScreenSaver + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + + File + + + + + Close + w + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup… + P + 1048576 + 2147483647 + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + + Edit + + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + + Find + + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1048576 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling + + 1048576 + 2147483647 + + + submenuAction: + + Spelling + + + + Spelling… + : + 1048576 + 2147483647 + + + + + + Check Spelling + ; + 1048576 + 2147483647 + + + + + + Check Spelling as You Type + + 1048576 + 2147483647 + + + + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + + Window + + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 1048576 + 2147483647 + + + submenuAction: + + Help + + + + YES + XScreenSaver Help + ? + 1048576 + 2147483647 + + + + + + + + _NSMainMenu + + + SaverRunner + + + + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + showHelp: + + + + 122 + + + + terminate: + + + + 139 + + + + hideOtherApplications: + + + + 146 + + + + hide: + + + + 152 + + + + unhideAllApplications: + + + + 153 + + + + cut: + + + + 175 + + + + paste: + + + + 176 + + + + redo: + + + + 178 + + + + selectAll: + + + + 179 + + + + undo: + + + + 180 + + + + copy: + + + + 181 + + + + showGuessPanel: + + + + 188 + + + + checkSpelling: + + + + 190 + + + + toggleContinuousSpellChecking: + + + + 192 + + + + performClose: + + + + 193 + + + + delete: + + + + 195 + + + + performZoom: + + + + 198 + + + + performFindPanelAction: + + + + 199 + + + + performFindPanelAction: + + + + 200 + + + + performFindPanelAction: + + + + 201 + + + + performFindPanelAction: + + + + 202 + + + + centerSelectionInVisibleArea: + + + + 203 + + + + pasteAsPlainText: + + + + 205 + + + + delegate + + + + 207 + + + + menubar + + + + 209 + + + + openPreferences: + + + + 212 + + + + aboutPanel: + + + + 213 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + MainMenu + + + 19 + + + + + + + + 24 + + + + + + + + + + + 5 + + + + + 23 + + + + + 92 + + + + + 197 + + + + + 56 + + + + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 129 + + + + + 131 + + + + + + + + 130 + + + + + 134 + + + + + 136 + + + + + 143 + + + + + 144 + + + + + 145 + + + + + 149 + + + + + 150 + + + + + 196 + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + 73 + + + + + 74 + + + + + 77 + + + + + 78 + + + + + 103 + + + + + + + + 106 + + + + + + + + 111 + + + + + 163 + + + + + + + + 169 + + + + + + + + + + + + + + + + + + + 156 + + + + + 157 + + + + + 158 + + + + + 160 + + + + + 164 + + + + + 168 + + + + + + + + 159 + + + + + + + + + + + + 154 + + + + + 155 + + + + + 161 + + + + + 162 + + + + + 167 + + + + + 171 + + + + + 172 + + + + + 173 + + + + + 174 + + + + + 184 + + + + + + + + 185 + + + + + + + + + + 187 + + + + + 189 + + + + + 191 + + + + + 204 + + + + + 206 + + + SaverRunner + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{72, 1365}, {344, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{84, 1182}, {225, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + 213 + + + + + SaverRunner + NSObject + + id + id + + + + aboutPanel: + id + + + openPreferences: + id + + + + menubar + NSMenu + + + menubar + + menubar + NSMenu + + + + IBProjectSource + OSX/SaverRunner.h + + + + + + NSApplication + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSApplication.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSApplicationScripting.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSColorPanel.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSHelpManager.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSPageLayout.h + + + + NSBrowser + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSBrowser.h + + + + NSControl + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSControl.h + + + + NSDocument + NSObject + + id + id + id + id + id + id + + + + printDocument: + id + + + revertDocumentToSaved: + id + + + runPageLayout: + id + + + saveDocument: + id + + + saveDocumentAs: + id + + + saveDocumentTo: + id + + + + IBFrameworkSource + AppKit.framework/Headers/NSDocument.h + + + + NSDocument + + IBFrameworkSource + AppKit.framework/Headers/NSDocumentScripting.h + + + + NSMatrix + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSMatrix.h + + + + NSMenu + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSMenu.h + + + + NSMenuItem + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSMenuItem.h + + + + NSMovieView + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSMovieView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSAccessibility.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSAlert.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSAnimation.h + + + + NSObject + + + + NSObject + + + + NSObject + + + + NSObject + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSComboBox.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSComboBoxCell.h + + + + NSObject + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSDatePickerCell.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSDragging.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSDrawer.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSFontManager.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSFontPanel.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSImage.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSKeyValueBinding.h + + + + NSObject + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSNibLoading.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSOutlineView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSPasteboard.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSSavePanel.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSSound.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSSpeechRecognizer.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSSpeechSynthesizer.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSSplitView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTabView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTableView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSText.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTextStorage.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTextView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTokenField.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTokenFieldCell.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSToolbar.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSToolbarItem.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSWindow.h + + + + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSInterfaceStyle.h + + + + NSResponder + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSResponder.h + + + + NSTableView + NSControl + + + + NSText + NSView + + + + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSClipView.h + + + + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSRulerView.h + + + + NSView + NSResponder + + + + NSWindow + + + + NSWindow + NSResponder + + + + NSWindow + + IBFrameworkSource + AppKit.framework/Headers/NSWindowScripting.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + YES + ../../xscreensaver.xcodeproj + 3 + + {9, 8} + {7, 2} + + + diff --git a/OSX/English.lproj/SaverRunner.nib/keyedobjects.nib b/OSX/English.lproj/SaverRunner.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..96d6891c19180e3ef02fa68453004348827e9178 GIT binary patch literal 13707 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 + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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. + */ + +#ifdef USE_IPHONE +# import +# define NSSlider UISlider +# define NSRect CGRect +# define minValue minimumValue +# define maxValue maximumValue +#else +# import +#endif + +@interface InvertedSlider : NSSlider +{ + BOOL inverted; + BOOL integers; +} + +- (id) initWithFrame:(NSRect)r inverted:(BOOL)_inv integers:(BOOL)_int; + +# ifdef USE_IPHONE +- (double) transformedValue; +- (void) setTransformedValue:(double)v; +# endif + +@end diff --git a/OSX/InvertedSlider.m b/OSX/InvertedSlider.m new file mode 100644 index 00000000..642a3e4f --- /dev/null +++ b/OSX/InvertedSlider.m @@ -0,0 +1,151 @@ +/* xscreensaver, Copyright (c) 2006-2013 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 + +- (id) initWithFrame:(NSRect)r +{ + self = [super initWithFrame:r]; + if (! self) return 0; + inverted = YES; + integers = NO; + return self; +} + +- (id) initWithFrame:(NSRect)r inverted:(BOOL)_inv integers:(BOOL)_int +{ + self = [self initWithFrame:r]; + inverted = _inv; + integers = _int; + return self; +} + + +-(double) transformValue:(double) value +{ + double v2 = (integers + ? (int) (value + (value < 0 ? -0.5 : 0.5)) + : value); + double low = [self minValue]; + double high = [self maxValue]; + double range = high - low; + double off = v2 - low; + if (inverted) + v2 = low + (range - off); + // NSLog (@" ... %.1f -> %.1f [%.1f - %.1f]", value, v2, low, high); + return v2; +} + +#ifndef USE_IPHONE + +/* On MacOS, we have to transform the value on every entry and exit point + to this class. So, we implement doubleValue and setDoubleValue to + transform the value; and we then have to re-implement every getter and + setter in terms of those. There's no way to simply change how the + slider is displayed without mucking with the value inside of it. + */ + +-(double) doubleValue +{ + return [self transformValue:[super doubleValue]]; +} + +-(void) setDoubleValue:(double)v +{ + return [super setDoubleValue:[self transformValue:v]]; +} + +-(float)floatValue { return (float) [self doubleValue]; } +-(int)intValue { return (int) [self doubleValue]; } +-(NSInteger)integerValue { return (NSInteger) [self doubleValue]; } +-(id)objectValue { return [NSNumber numberWithDouble:[self doubleValue]]; } + +-(NSString *)stringValue +{ + if (integers) + return [NSString stringWithFormat:@"%d", [self intValue]]; + else + return [NSString stringWithFormat:@"%f", [self doubleValue]]; +} + +- (NSAttributedString *)attributedStringValue; +{ + // #### "Build and Analyze" says this leaks. Unsure whether this is true. + return [[NSAttributedString alloc] initWithString:[self stringValue]]; +} + +-(void)setFloatValue:(float)v { [self setDoubleValue: (double) v]; } +-(void)setIntValue: (int)v { [self setDoubleValue: (double) v]; } +-(void)setIntegerValue:(NSInteger)v { [self setDoubleValue: (double) v]; } +-(void)setStringValue:(NSString *)v { [self setDoubleValue: [v doubleValue]]; } +-(void)takeIntValueFrom:(id)f { [self setIntValue: [f intValue]]; } +-(void)takeFloatValueFrom:(id)f { [self setFloatValue: [f floatValue]]; } +-(void)takeDoubleValueFrom:(id)f { [self setDoubleValue: [f doubleValue]]; } +-(void)takeStringValueFrom:(id)f { [self setStringValue: [f stringValue]]; } +-(void)takeObjectValueFrom:(id)f { [self setObjectValue: [f objectValue]]; } +-(void)takeIntegerValueFrom:(id)f { [self setIntegerValue:[f integerValue]];} +-(void) setAttributedStringValue:(NSAttributedString *)v { + [self setStringValue:[v string]]; +} + +-(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]]; +} + +#else // USE_IPHONE + +/* On iOS, we have control over how the value is displayed, but there's no + way to transform the value on input and output: if we wrap 'value' and + 'setValue' analagously to what we do on MacOS, things fail in weird + ways. Presumably some parts of the system are accessing the value + instance variable directly instead of going through the methods. + + So the only way around this is to enforce that all of our calls into + this object use a new API: 'transformedValue' and 'setTransformedValue'. + The code in XScreenSaverConfigSheet uses that instead. + */ + +- (CGRect)thumbRectForBounds:(CGRect)bounds + trackRect:(CGRect)rect + value:(float)value +{ + CGRect thumb = [super thumbRectForBounds: bounds + trackRect: rect + value: [self transformValue:value]]; + if (inverted) + thumb.origin.x = rect.size.width - thumb.origin.x - thumb.size.width; + return thumb; +} + +-(double) transformedValue +{ + return [self transformValue: [self value]]; +} + +-(void) setTransformedValue:(double)v +{ + [self setValue: [self transformValue: v]]; +} + +#endif // USE_IPHONE + + +@end diff --git a/OSX/Makefile b/OSX/Makefile new file mode 100644 index 00000000..28588ee8 --- /dev/null +++ b/OSX/Makefile @@ -0,0 +1,233 @@ +# XScreenSaver for MacOS X, Copyright (c) 2006-2013 by Jamie Zawinski. + +XCODEBUILD = /usr/bin/xcodebuild +TARGETS = -target "All Savers" +ARCH = -arch i386 -arch x86_64 +CERT = 'Jamie Zawinski' +CERT = 'iPhone Developer: Jamie Zawinski (Y5M82TL69N)' +THUMBDIR = $(HOME)/www/xscreensaver/screenshots/ +PKGID = org.jwz.xscreensaver +SETFILE = /Applications/Xcode.app/Contents/Developer/Tools/SetFile +SETICON = /usr/local/bin/seticon + +default: release +all: debug release + +clean: + -rm -rf build +# cd ..; $(XCODEBUILD) $(TARGETS) clean + +distclean: + -rm -f config.status config.cache config.log \ + *.bak *.rej TAGS *~ "#"* + -rm -rf autom4te*.cache + -rm -rf build Sparkle.framework + +distdepend:: Sparkle.framework +distdepend:: update_plist_version + +debug: distdepend + cd ..; $(XCODEBUILD) $(ARCH) $(TARGETS) -configuration Debug build + +release:: distdepend + cd ..; $(XCODEBUILD) $(ARCH) $(TARGETS) -configuration Release build + +release:: check_versions +release:: update_thumbs +release:: sign + +Sparkle.framework: + unzip ../archive/Sparkle.framework-2013-12-04.zip + +sign: + @for f in build/Release/*.app/Contents/*/*.saver \ + build/Release/*.{saver,app} ; do \ + codesign --deep -vfs $(CERT) $$f ; \ + done + +check_versions: + @\ + SRC=../utils/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' $$SRC` ; \ + DIR=build/Release ; \ + RESULT=0 ; \ + for S in $$DIR/*.{saver,app} ; do \ + for P in $$S/Contents/Info.plist ; do \ + V2=`plutil -convert xml1 -o - "$$P" | \ + perl -0000 -n -e \ + 'm@CFBundleVersion\s*(.*?)@si \ + && print $$1'` ; \ + if [ "$$V2" != "$$V" ] ; then \ + echo "Wrong version: $$S ($$V2)" ; \ + RESULT=1 ; \ + fi ; \ + done ; \ + done ; \ + if [ "$$RESULT" = 0 ]; then echo "Versions match ($$V2)" ; fi ; \ + exit $$RESULT + +update_thumbs:: + ./update-thumbnail.pl $(THUMBDIR) build/Release/*.saver + + +# Arrrrgh +ios-function-table.m:: + @./build-fntable.pl build/Debug-iphonesimulator/XScreenSaver.app $@ + + +echo_tarfiles: + @echo `find . \ + \( \( -name '.??*' -o -name build -o -name CVS -o -name '*~*' \ + -o -name 'jwz.*' -o -name 'Screen Savers' \) \ + -prune \) \ + -o \( -type f -o -type l \) -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 *.plist ; do \ + /bin/echo -n "Updating version number in $$S to \"$$V\"... " ; \ + KEYS="CFBundleVersion|CFBundleShortVersionString|CFBundleLongVersionString|CFBundleGetInfoString|NSHumanReadableCopyright" ; \ + 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 + + +updates.xml:: + ./updates.pl xscreensaver ../README ../archive ~/www/xscreensaver + @$(MAKE) test_sig + +test_sig:: + @ \ + U=../utils/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ;]*\).*/\1/p' < $$U` ; \ + BASE="xscreensaver-$$V" ; \ + OUTDIR="../archive" ; \ + DMG="$$OUTDIR/$$BASE.dmg" ; \ + SIG=`sed -n 's/^.*dsaSignature="\(.*\)".*/\1/p' updates.xml` ; \ + PUB="sparkle_dsa_pub.pem" ; \ + NN="t.$$$$" ; \ + SIGB=/tmp/$$NN.sig ; \ + HASH=/tmp/$$NN.hash ; \ + rm -f "$$SIGB" "$$HASH" ; \ + echo "$$SIG " | base64 -D > "$$SIGB" ; \ + set -e ; \ + for OPENSSL in /usr/bin/openssl /opt/local/bin/openssl ; do \ + $$OPENSSL dgst -sha1 -binary < "$$DMG" > "$$HASH" ; \ + /bin/echo -n "$$OPENSSL `$$OPENSSL version`: " ; \ + $$OPENSSL dgst -dss1 -verify "$$PUB" -signature "$$SIGB" "$$HASH" ; \ + done ; \ + rm -f "$$SIGB" "$$HASH" ; \ + + +build/Release/installer.pkg: installer.rtf installer.xml installer.sh installer.png ../utils/version.h + @\ + set -e ; \ + SRC=../utils/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' $$SRC` ; \ + \ + DIST="installer.xml" ; \ + STAGE="build/Release/pkg_stage" ; \ + PKG1="$@" ; \ + PKG2="$$STAGE/contents.pkg" ; \ + SCRIPTS="$$STAGE/scripts" ; \ + RES="$$STAGE/resources" ; \ + \ + set -x ; \ + rm -rf "$$STAGE" ; \ + mkdir -p "$$SCRIPTS" "$$RES" ; \ + \ + cp -p installer.sh "$$SCRIPTS/preinstall" ; \ + cp -p installer.png "$$RES/background.png" ; \ + cp -p installer.rtf "$$RES/welcome.rtf" ; \ + \ + pkgbuild --identifier "$(PKGID)" --version "$$V" \ + --scripts "$$SCRIPTS" --nopayload "$$PKG2" ; \ + codesign -vfs $(CERT) "$$PKG2" ; \ + codesign -vd "$$PKG2" ; \ + \ + productbuild --distribution "$$DIST" --resources "$$RES" \ + --package-path "$$STAGE" --version "$$V" "$$PKG1" ; \ + codesign -vfs $(CERT) "$$PKG1" ; \ + codesign -vd "$$PKG1" ; \ + \ + rm -rf "$$STAGE" ; \ + + +# -format UDBZ saves 4% (~1.2 MB) over UDZO. +dmg:: distdepend check_versions build/Release/installer.pkg + @ \ + set -e ; \ + SRC=../utils/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' $$SRC` ; \ + TMPDIR="build" ; \ + SRC="build/Release" ; \ + EXTRAS=../../xdaliclock/OSX/build/Release/*.saver ; \ + BASE="xscreensaver-$$V" ; \ + OUTDIR="../archive" ; \ + DMG="$$OUTDIR/$$BASE.dmg" ; \ + TMPDMG="$$TMPDIR/tmp.dmg" ; \ + VOLNAME="XScreenSaver $$V" ; \ + STAGE="$$TMPDIR/dmg_stage" ; \ + DST="$$STAGE/Screen Savers" ; \ + PKG="$$STAGE/Install Everything.pkg" ; \ + rm -f "$$DMG" ; \ + rm -rf "$$STAGE" ; \ + echo + mkdir -p "$$DST" ; \ + mkdir -p "$$DST" ; \ + \ + retired=`perl -0 -ne \ + 's/\\\\\\n//g; m/^RETIRED_EXES\s*=\s*(.*)$$/m && print "$$1\n"' \ + ../hacks/Makefile.in ; \ + perl -0 -ne \ + 's/\\\\\\n//g; m/^RETIRED_GL_EXES\s*=\s*(.*)$$/m && print "$$1\n"' \ + ../hacks/glx/Makefile.in ; \ + echo xscreensaver ; \ + echo savertester` ; \ + \ + for f in $$SRC/*.{saver,app} $$EXTRAS ; do \ + ok=yes ; \ + ff=`echo $$f | perl -e '$$_=<>; s@^.*/(.*)\..*$$@\L$$1@; print'`; \ + for r in $$retired ; do \ + if [ "$$ff" = "$$r" ]; then ok=no ; fi ; \ + done ; \ + if [ "$$ok" = yes ]; then \ + echo + cp -pR "$$f" "$$DST/" ; \ + cp -pR "$$f" "$$DST/" ; \ + else \ + echo skipping "$$f" ; \ + fi ; \ + done ; \ + set -x ; \ + cp -p bindist.rtf "$$STAGE/Read Me.rtf" ; \ + cp -p build/Release/installer.pkg "$$PKG" ; \ + cp -p bindist-DS_Store "$$STAGE/.DS_Store" ; \ + cp -p bindist.webloc "$$STAGE/Get the iPhone:iPad Version.webloc" ; \ + cp -p XScreenSaverDMG.icns "$$STAGE/.VolumeIcon.icns" ; \ + ${SETFILE} -a C "$$STAGE" ; \ + ${SETFILE} -a E "$$STAGE"/*.{rtf,pkg,webloc} ; \ + $(SETICON) -d ../../xdaliclock/OSX/daliclockSaver.icns \ + "$$DST/DaliClock.saver" ; \ + $(SETICON) -d XScreenSaverFolder.icns "$$DST" ; \ + $(SETICON) -d XScreenSaverWebloc.icns "$$STAGE"/*.webloc ; \ + $(SETICON) -d XScreenSaverPkg.icns "$$STAGE"/*.pkg ; \ + 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" ; \ + xattr -w com.apple.quarantine "0000;00000000;;" "$$DMG" ; \ + rm -f "$$TMPDMG" ; \ + ls -ldhgF "$$DMG" diff --git a/OSX/PrefsReader.h b/OSX/PrefsReader.h new file mode 100644 index 00000000..492d4eaf --- /dev/null +++ b/OSX/PrefsReader.h @@ -0,0 +1,56 @@ +/* xscreensaver, Copyright (c) 2006-2013 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). + */ + +#ifdef USE_IPHONE +# import +# import +# define NSUserDefaultsController NSUserDefaults +#else +# import +#endif + + +#import "jwxyz.h" + +@interface PrefsReader : NSObject +{ + NSString *saver_name; + + NSUserDefaults *userDefaults; // this is actually a 'ScreenSaverDefaults' + NSUserDefaultsController *userDefaultsController; + + NSUserDefaults *globalDefaults; // for prefs shared by all xscreensavers. + NSUserDefaultsController *globalDefaultsController; + + NSDictionary *defaultOptions; // Hardcoded defaults before any changes. +} + +- (id) initWithName: (NSString *) name + xrmKeys: (const XrmOptionDescRec *) opts + defaults: (const char * const *) defs; + +- (NSUserDefaultsController *) userDefaultsController; +- (NSUserDefaultsController *) globalDefaultsController; +- (NSDictionary *) defaultOptions; + +- (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..cf1698ec --- /dev/null +++ b/OSX/PrefsReader.m @@ -0,0 +1,571 @@ +/* xscreensaver, Copyright (c) 2006-2013 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). + */ + +#ifndef USE_IPHONE +# import +#endif + +#import "PrefsReader.h" +#import "Updater.h" +#import "screenhackI.h" + +#ifndef USE_IPHONE + + +/* GlobalDefaults is an NSUserDefaults implementation that writes into + the preferences key we provide, instead of whatever the default would + be for this app. We do this by invoking the Core Foundation preferences + routines directly, while presenting the same API as NSUserDefaults. + + We need this so that global prefs will go into the file + Library/Preferences/org.jwz.xscreensaver.updater.plist instead of into + Library/Preferences/ByHost/org.jwz.xscreensaver.Maze.XXXXX.plist + with the per-saver prefs. + + The ScreenSaverDefaults class *almost* does this, but it always writes + into the ByHost subdirectory, which means it's not readable by an app + that tries to access it with a plain old +standardUserDefaults. + */ +@interface GlobalDefaults : NSUserDefaults +{ + NSString *domain; + NSDictionary *defaults; +} +@end + +@implementation GlobalDefaults +- (id) initWithDomain:(NSString *)_domain +{ + self = [super init]; + domain = [_domain retain]; + return self; +} + +- (void) dealloc +{ + [domain release]; + [defaults release]; + [super dealloc]; +} + +- (void)registerDefaults:(NSDictionary *)dict +{ + defaults = [dict retain]; +} + +- (id)objectForKey:(NSString *)key +{ + NSObject *obj = (NSObject *) + CFPreferencesCopyAppValue ((CFStringRef) key, (CFStringRef) domain); + if (!obj && defaults) + obj = [defaults objectForKey:key]; + return obj; +} + +- (void)setObject:(id)value forKey:(NSString *)key +{ + if (value && defaults) { + // If the value is the default, then remove it instead. + NSObject *def = [defaults objectForKey:key]; + if (def && [def isEqual:value]) + value = NULL; + } + CFPreferencesSetAppValue ((CFStringRef) key, + (CFPropertyListRef) value, + (CFStringRef) domain); +} + + +- (BOOL)synchronize +{ + return CFPreferencesAppSynchronize ((CFStringRef) domain); +} + + +// Make sure these all call our objectForKey. +// Might not be necessary, but safe. + +- (NSString *)stringForKey:(NSString *)key +{ + return [[self objectForKey:key] stringValue]; +} + +- (NSArray *)arrayForKey:(NSString *)key +{ + return (NSArray *) [self objectForKey:key]; +} + +- (NSDictionary *)dictionaryForKey:(NSString *)key +{ + return (NSDictionary *) [self objectForKey:key]; +} + +- (NSData *)dataForKey:(NSString *)key +{ + return (NSData *) [self objectForKey:key]; +} + +- (NSArray *)stringArrayForKey:(NSString *)key +{ + return (NSArray *) [self objectForKey:key]; +} + +- (NSInteger)integerForKey:(NSString *)key +{ + return [[self objectForKey:key] integerValue]; +} + +- (float)floatForKey:(NSString *)key +{ + return [[self objectForKey:key] floatValue]; +} + +- (double)doubleForKey:(NSString *)key +{ + return [[self objectForKey:key] doubleValue]; +} + +- (BOOL)boolForKey:(NSString *)key +{ + return [[self objectForKey:key] integerValue]; +} + +// Make sure these all call our setObject. +// Might not be necessary, but safe. + +- (void)removeObjectForKey:(NSString *)key +{ + [self setObject:NULL forKey:key]; +} + +- (void)setInteger:(NSInteger)value forKey:(NSString *)key +{ + [self setObject:[NSNumber numberWithInteger:value] forKey:key]; +} + +- (void)setFloat:(float)value forKey:(NSString *)key +{ + [self setObject:[NSNumber numberWithFloat:value] forKey:key]; +} + +- (void)setDouble:(double)value forKey:(NSString *)key +{ + [self setObject:[NSNumber numberWithDouble:value] forKey:key]; +} + +- (void)setBool:(BOOL)value forKey:(NSString *)key +{ + [self setObject:[NSNumber numberWithBool:value] forKey:key]; +} +@end + + +#endif // !USE_IPHONE + + +@implementation PrefsReader + +/* Normally we read resources by looking up "KEY" in the database + "org.jwz.xscreensaver.SAVERNAME". But in the all-in-one iPhone + app, everything is stored in the database "org.jwz.xscreensaver" + instead, so transform keys to "SAVERNAME.KEY". + + NOTE: This is duplicated in XScreenSaverConfigSheet.m, cause I suck. + */ +- (NSString *) makeKey:(NSString *)key +{ +# ifdef USE_IPHONE + NSString *prefix = [saver_name stringByAppendingString:@"."]; + if (! [key hasPrefix:prefix]) // Don't double up! + key = [prefix stringByAppendingString:key]; +# endif + return key; +} + +- (NSString *) makeCKey:(const char *)key +{ + return [self makeKey:[NSString stringWithCString:key + encoding:NSUTF8StringEncoding]]; +} + + +/* 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 = [self makeCKey:key]; + 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: \"%@\" = \"%@\" [%@]", 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]; + [globalDefaults registerDefaults:UPDATER_DEFAULTS]; + + // Save a copy of the default options, since iOS doesn't have + // [userDefaultsController initialValues]. + // + if (defaultOptions) + [defaultOptions release]; + defaultOptions = [[NSMutableDictionary dictionaryWithCapacity:20] + retain]; + for (NSString *key in defsdict) { + [defaultOptions setValue:[defsdict objectForKey:key] forKey:key]; + } + +# ifndef USE_IPHONE + userDefaultsController = + [[NSUserDefaultsController alloc] initWithDefaults:userDefaults + initialValues:defsdict]; + globalDefaultsController = + [[NSUserDefaultsController alloc] initWithDefaults:globalDefaults + initialValues:defsdict]; +# else // USE_IPHONE + userDefaultsController = userDefaults; + globalDefaultsController = userDefaults; +# endif // USE_IPHONE + + 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 = [self makeCKey:resource]; + + // 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, "foreground") || + !strcmp(resource, "textLiteral") || + !strcmp(resource, "textFile") || + !strcmp(resource, "textURL") || + !strcmp(resource, "textProgram") || + !strcmp(resource, "imageDirectory"))) + NSLog (@"warning: \"%s\" is in options but not defaults", resource); + } + [optsdict setValue:nsresource forKey:nsresource]; + + opts++; + } + +#if 0 + // make sure there's no resource mentioned in defaults and not options. + for (NSString *key in defsdict) { + 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 */ + +#if 0 + // Dump the entire resource database. + NSLog(@"userDefaults:"); + NSDictionary *d = [userDefaults dictionaryRepresentation]; + for (NSObject *key in [[d allKeys] + sortedArrayUsingSelector:@selector(compare:)]) { + NSObject *val = [d objectForKey:key]; + NSLog (@"%@ = %@", key, val); + } + NSLog(@"globalDefaults:"); + d = [globalDefaults dictionaryRepresentation]; + for (NSObject *key in [[d allKeys] + sortedArrayUsingSelector:@selector(compare:)]) { + NSObject *val = [d objectForKey:key]; + NSLog (@"%@ = %@", key, val); + } +#endif + +} + +- (NSUserDefaultsController *) userDefaultsController +{ + NSAssert(userDefaultsController, @"userDefaultsController uninitialized"); + return userDefaultsController; +} + +- (NSUserDefaultsController *) globalDefaultsController +{ + NSAssert(globalDefaultsController, @"globalDefaultsController uninitialized"); + return globalDefaultsController; +} + +- (NSDictionary *) defaultOptions +{ + NSAssert(defaultOptions, @"defaultOptions uninitialized"); + return defaultOptions; +} + + +- (NSObject *) getObjectResource: (const char *) name +{ + // First look in userDefaults, then in globalDefaults. + for (int globalp = 0; globalp <= 1; globalp++) { + const char *name2 = name; + while (1) { + NSString *key = [self makeCKey:name2]; + NSObject *obj = [(globalp ? globalDefaults : 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 (name2, '.'); + if (dot && dot[1]) + name2 = dot + 1; + else + break; + } + } + return NULL; +} + + +- (char *) getStringResource: (const char *) name +{ + NSObject *o = [self getObjectResource:name]; + //NSLog(@"%s = %@",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, "fpsFont") || // fps.c + !strcmp(name, "foreground") || // fps.c + !strcmp(name, "background") || + !strcmp(name, "textLiteral") + )) + NSLog(@"warning: no preference \"%s\" [string]", name); + return NULL; + } + if (! [o isKindOfClass:[NSString class]]) { + NSLog(@"asked for %s as a string, but it is a %@", name, [o class]); + o = [(NSNumber *) o stringValue]; + } + + NSString *os = (NSString *) o; + char *result = strdup ([os cStringUsingEncoding:NSUTF8StringEncoding]); + + // Kludge: if the string is surrounded with single-quotes, remove them. + // This happens when the .xml file says things like arg="-foo 'bar baz'" + if (result[0] == '\'' && result[strlen(result)-1] == '\'') { + result[strlen(result)-1] = 0; + strcpy (result, result+1); + } + + // Kludge: assume that any string that begins with "~" and has a "/" + // anywhere in it should be expanded as if it is a pathname. + if (result[0] == '~' && strchr (result, '/')) { + os = [NSString stringWithCString:result encoding:NSUTF8StringEncoding]; + free (result); + result = strdup ([[os stringByExpandingTildeInPath] + cStringUsingEncoding:NSUTF8StringEncoding]); + } + + return 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, "doFPS") || // fps.c + !strcmp(name, "eraseSeconds") // erase.c + )) + NSLog(@"warning: no preference \"%s\" [float]", 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 +{ + // Sliders might store float values for integral resources; round them. + float v = [self getFloatResource:name]; + int i = (int) (v + (v < 0 ? -0.5 : 0.5)); // ignore sign or -1 rounds to 0 + // if (i != v) NSLog(@"%s: rounded %.3f to %d", name, v, i); + return i; +} + + +- (BOOL) getBooleanResource: (const char *) name +{ + NSObject *o = [self getObjectResource:name]; + if (! o) { + return NO; + } else if ([o isKindOfClass:[NSNumber class]]) { + double n = [(NSNumber *) o doubleValue]; + if (n == 0) return NO; + else if (n == 1) return YES; + else goto FAIL; + } else if ([o isKindOfClass:[NSString class]]) { + NSString *s = [((NSString *) o) lowercaseString]; + if ([s isEqualToString:@"true"] || + [s isEqualToString:@"yes"] || + [s isEqualToString:@"1"]) + return YES; + else if ([s isEqualToString:@"false"] || + [s isEqualToString:@"no"] || + [s isEqualToString:@"0"] || + [s isEqualToString:@""]) + return NO; + else + goto FAIL; + } else { + FAIL: + NSAssert2(0, @"%s = \"%@\" but should have been a boolean", name, o); + abort(); + } +} + + +- (id) initWithName: (NSString *) name + xrmKeys: (const XrmOptionDescRec *) opts + defaults: (const char * const *) defs +{ + self = [self init]; + if (!self) return nil; + +# ifndef USE_IPHONE + userDefaults = [ScreenSaverDefaults defaultsForModuleWithName:name]; + globalDefaults = [[[GlobalDefaults alloc] initWithDomain:@UPDATER_DOMAIN] + retain]; +# else // USE_IPHONE + userDefaults = [NSUserDefaults standardUserDefaults]; + globalDefaults = userDefaults; +# endif // USE_IPHONE + + // Convert "org.jwz.xscreensaver.NAME" to just "NAME". + NSRange r = [name rangeOfString:@"." options:NSBackwardsSearch]; + if (r.length) + name = [name substringFromIndex:r.location+1]; + name = [name stringByReplacingOccurrencesOfString:@" " withString:@""]; + saver_name = [name retain]; + + [self registerXrmKeys:opts defaults:defs]; + return self; +} + +- (void) dealloc +{ + [saver_name release]; + [userDefaultsController release]; + [globalDefaultsController release]; + [super dealloc]; +} + +@end diff --git a/OSX/README b/OSX/README new file mode 100644 index 00000000..f8f7458b --- /dev/null +++ b/OSX/README @@ -0,0 +1,40 @@ + +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.4 or later is required. +To run them, MacOS 10.4.0 or later is required. + + +This is how you add a new screen saver to the Xcode project. It's a +ridiculously long list of steps! + + 1: Duplicate a target (Dangerball for GL, or Attraction for X11). + 2: Rename it, and drag it to the right spot in the list. + 3: Delete the dangerball.c and dangerball.xml files from the new target. + 4: Delete the "DangerBall copy-Info.plist" file that got created. + 5: Delete the "DangerBall copy-Info.plist" from the Build Settings too. + 6: Change PRODUCT_NAME in Build Settings. + 7: Manage Schemes, rename "DangerBall Copy". + 8: Move to the right place in the list. + 9: Scheme / Run: set SELECTED_SAVER environment variable. + 10: Scheme / Run / Info: Executable: SaverTester.app. + 11: File / Add Files / the new .c and .xml. + Add to targets: the new target, and also "XScreenSaver-iOS". + 12: Re-order them in the file list. + 13: In target "All Savers (OpenGL)" add the new target as a dependency. + 14: In target "XScreenSaver-iOS", reorder new files in "Copy" and "Compile". + 15: In target "XScreenSaver-iOS", add "-DUSE_GL" to the new file's options. + 16: Put a 200x150 screen shot in ~/www/xscreensaver/screenshots/ + 17: ln -s ../../src/xscreensaver/OSX/build/Debug/NEW.saver \ + ~/Library/Screen\ Savers/ + 18: Build "XScreenSaver-iOS" once. then: + cd ~/src/xscreensaver/OSX ; make ios-function-table.m + and build it again. + 19: cvs add xscreensaver.xcodeproj/xcuserdata/*/xcschemes/*.xcscheme + 20: Don't forget to create a man page from the XML with xml2man.pl, + and update Makefile.in. diff --git a/OSX/SaverListController.h b/OSX/SaverListController.h new file mode 100644 index 00000000..fef8a78e --- /dev/null +++ b/OSX/SaverListController.h @@ -0,0 +1,36 @@ +/* xscreensaver, Copyright (c) 2012 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 top-level screen-saver selection list in the iOS app. + */ + +#ifdef USE_IPHONE + +#import + +@interface SaverListController : UITableViewController { + + int active_section_count; + NSMutableArray *list_by_letter[26]; // 27 to get "#" after "Z". + NSMutableArray *letter_sections; + NSMutableArray *section_titles; + NSDictionary *descriptions; + + int tap_count; + NSTimer *tap_timer; + NSIndexPath *last_tap; +} + +- (id)initWithNames:(NSArray *)names descriptions:(NSDictionary *)descs; +- (void) reload:(NSArray *)names descriptions:(NSDictionary *)descs; +- (void) scrollTo:(NSString *)name; +@end + +#endif // USE_IPHONE diff --git a/OSX/SaverListController.m b/OSX/SaverListController.m new file mode 100644 index 00000000..e0abeca6 --- /dev/null +++ b/OSX/SaverListController.m @@ -0,0 +1,351 @@ +/* xscreensaver, Copyright (c) 2012-2013 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 top-level screen-saver selection list in the iOS app. + */ + +#ifdef USE_IPHONE // whole file + + +#import "SaverListController.h" +#import "SaverRunner.h" +#import "yarandom.h" +#import "version.h" + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + + +@implementation SaverListController + +- (void) titleTapped:(id) sender +{ + [[UIApplication sharedApplication] + openURL:[NSURL URLWithString:@"http://www.jwz.org/xscreensaver/"]]; +} + + +- (void)makeTitleBar +{ + // Extract the version number and release date from the version string. + // Here's an area where I kind of wish I had "Two Problems". + // I guess I could add custom key to the Info.plist for this. + + NSArray *a = [[NSString stringWithCString: screensaver_id + encoding:NSASCIIStringEncoding] + componentsSeparatedByCharactersInSet: + [NSCharacterSet + characterSetWithCharactersInString:@" ()-"]]; + NSString *vers = [a objectAtIndex: 3]; + NSString *year = [a objectAtIndex: 7]; + + NSString *line1 = [@"XScreenSaver " stringByAppendingString: vers]; + NSString *line2 = [@"\u00A9 " stringByAppendingString: + [year stringByAppendingString: + @" Jamie Zawinski "]]; + + UIView *v = [[UIView alloc] initWithFrame:CGRectZero]; + + // The "go to web page" button on the right + + UIImage *img = [UIImage imageWithContentsOfFile: + [[[NSBundle mainBundle] bundlePath] + stringByAppendingPathComponent: + @"iSaverRunner29t.png"]]; + UIBarButtonItem *button = [[[UIBarButtonItem alloc] + initWithImage: img + style: UIBarButtonItemStylePlain + target: self + action: @selector(titleTapped:)] + autorelease]; + button.width = img.size.width; + self.navigationItem.rightBarButtonItem = button; + + // The title bar + + UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectZero]; + UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectZero]; + [label1 setText: line1]; + [label2 setText: line2]; + [label1 setBackgroundColor:[UIColor clearColor]]; + [label2 setBackgroundColor:[UIColor clearColor]]; + + [label1 setFont: [UIFont boldSystemFontOfSize: 17]]; + [label2 setFont: [UIFont systemFontOfSize: 12]]; + [label1 sizeToFit]; + [label2 sizeToFit]; + + CGRect r1 = [label1 frame]; + CGRect r2 = [label2 frame]; + CGRect r3 = r2; + + CGRect win = [self view].frame; + if (win.size.width > 320) { // iPad + [label1 setTextAlignment: UITextAlignmentLeft]; + [label2 setTextAlignment: UITextAlignmentRight]; + label2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + r3.size.width = win.size.width; + r1 = r3; + r1.origin.x += 6; + r1.size.width -= 12; + r2 = r1; + + } else { // iPhone + r3.size.width = 320; // force it to be flush-left + [label1 setTextAlignment: UITextAlignmentLeft]; + [label2 setTextAlignment: UITextAlignmentLeft]; + r1.origin.y = -1; // make it fit in landscape + r2.origin.y = r1.origin.y + r1.size.height - 2; + r3.size.height = r1.size.height + r2.size.height; + } + v.autoresizingMask = UIViewAutoresizingFlexibleWidth; + [label1 setFrame:r1]; + [label2 setFrame:r2]; + [v setFrame:r3]; + + [v addSubview:label1]; + [v addSubview:label2]; + + self.navigationItem.titleView = v; +} + + +- (id)initWithNames:(NSArray *)names descriptions:(NSDictionary *)descs; +{ + self = [self init]; + if (! self) return 0; + [self reload:names descriptions:descs]; + [self makeTitleBar]; + return self; +} + + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tv +{ + int n = countof(list_by_letter); + NSMutableArray *a = [NSMutableArray arrayWithCapacity: n]; + for (int i = 0; i < n; i++) { + char s[2]; + s[0] = (i == 'Z'-'A'+1 ? '#' : i+'A'); + s[1] = 0; + [a addObject: [NSString stringWithCString:s + encoding:NSASCIIStringEncoding]]; + } + return a; +} + + +- (void) reload:(NSArray *)names descriptions:(NSDictionary *)descs +{ + if (descriptions) + [descriptions release]; + descriptions = [descs retain]; + + int n = countof(list_by_letter); + for (int i = 0; i < n; i++) { + list_by_letter[i] = [[NSMutableArray alloc] init]; + } + + for (NSString *name in names) { + int index = ([name cStringUsingEncoding: NSASCIIStringEncoding])[0]; + if (index >= 'a' && index <= 'z') + index -= 'a'-'A'; + if (index >= 'A' && index <= 'Z') + index -= 'A'; + else + index = n-1; + [list_by_letter[index] addObject: name]; + } + + active_section_count = 0; + letter_sections = [[[NSMutableArray alloc] init] retain]; + section_titles = [[[NSMutableArray alloc] init] retain]; + for (int i = 0; i < n; i++) { + if ([list_by_letter[i] count] > 0) { + active_section_count++; + [letter_sections addObject: list_by_letter[i]]; + if (i <= 'Z'-'A') + [section_titles addObject: [NSString stringWithFormat: @"%c", i+'A']]; + else + [section_titles addObject: @"#"]; + } + } + [self.tableView reloadData]; +} + + +- (NSString *)tableView:(UITableView *)tv + titleForHeaderInSection:(NSInteger)section +{ + return [section_titles objectAtIndex: section]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv +{ + return active_section_count; +} + + +- (NSInteger)tableView:(UITableView *)tv + numberOfRowsInSection:(NSInteger)section +{ + return [[letter_sections objectAtIndex: section] count]; +} + +- (NSInteger)tableView:(UITableView *)tv + sectionForSectionIndexTitle:(NSString *)title + atIndex:(NSInteger) index +{ + int i = 0; + for (NSString *sectionTitle in section_titles) { + if ([sectionTitle isEqualToString: title]) + return i; + i++; + } + return -1; +} + + +- (UITableViewCell *)tableView:(UITableView *)tv + cellForRowAtIndexPath:(NSIndexPath *)ip +{ + NSString *id = + [[letter_sections objectAtIndex: [ip indexAtPosition: 0]] + objectAtIndex: [ip indexAtPosition: 1]]; + NSString *desc = [descriptions objectForKey:id]; + + UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier: id]; + if (!cell) { + cell = [[[UITableViewCell alloc] + initWithStyle: (desc + ? UITableViewCellStyleSubtitle + : UITableViewCellStyleDefault) + reuseIdentifier: id] + autorelease]; + cell.textLabel.text = id; + + cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; + if (desc) + cell.detailTextLabel.text = desc; + } + return cell; +} + + +/* Selecting a row launches the saver. + */ +- (void)tableView:(UITableView *)tv + didSelectRowAtIndexPath:(NSIndexPath *)ip +{ + UITableViewCell *cell = [tv cellForRowAtIndexPath: ip]; + SaverRunner *s = + (SaverRunner *) [[UIApplication sharedApplication] delegate]; + if (! s) return; + NSAssert ([s isKindOfClass:[SaverRunner class]], @"not a SaverRunner"); + [s loadSaver: cell.textLabel.text]; +} + +/* Selecting a row's Disclosure Button opens the preferences. + */ +- (void)tableView:(UITableView *)tv + accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)ip +{ + UITableViewCell *cell = [tv cellForRowAtIndexPath: ip]; + SaverRunner *s = + (SaverRunner *) [[UIApplication sharedApplication] delegate]; + if (! s) return; + NSAssert ([s isKindOfClass:[SaverRunner class]], @"not a SaverRunner"); + [s openPreferences: cell.textLabel.text]; +} + + +- (void) scrollTo: (NSString *) name +{ + int i = 0; + int j = 0; + Bool ok = NO; + for (NSArray *a in letter_sections) { + j = 0; + for (NSString *n in a) { + ok = [n isEqualToString: name]; + if (ok) goto DONE; + j++; + } + i++; + } + DONE: + if (ok) { + NSIndexPath *ip = [NSIndexPath indexPathForRow: j inSection: i]; + [self.tableView selectRowAtIndexPath:ip + animated:NO + scrollPosition: UITableViewScrollPositionMiddle]; + } +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o +{ + return YES; +} + + +/* We need this to respond to "shake" gestures + */ +- (BOOL)canBecomeFirstResponder +{ + return YES; +} + +- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ +} + +- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ +} + + +/* Shake means load a random screen saver. + */ +- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + if (motion != UIEventSubtypeMotionShake) + return; + NSMutableArray *a = [NSMutableArray arrayWithCapacity: 200]; + for (NSArray *sec in letter_sections) + for (NSString *s in sec) + [a addObject: s]; + int n = [a count]; + if (! n) return; + NSString *which = [a objectAtIndex: (random() % n)]; + + SaverRunner *s = + (SaverRunner *) [[UIApplication sharedApplication] delegate]; + if (! s) return; + NSAssert ([s isKindOfClass:[SaverRunner class]], @"not a SaverRunner"); + [self scrollTo: which]; + [s loadSaver: which]; +} + + +- (void)dealloc +{ + for (int i = 0; i < countof(list_by_letter); i++) + [list_by_letter[i] release]; + [letter_sections release]; + [section_titles release]; + [descriptions release]; + [super dealloc]; +} + +@end + + +#endif // USE_IPHONE -- whole file diff --git a/OSX/SaverRunner.h b/OSX/SaverRunner.h new file mode 100644 index 00000000..c58e2b33 --- /dev/null +++ b/OSX/SaverRunner.h @@ -0,0 +1,77 @@ +/* xscreensaver, Copyright (c) 2006-2013 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. + */ + +#ifdef USE_IPHONE +# import +# import +# import +# import +# import +# import +# define NSView UIView +# define NSRect CGRect +# define NSSize CGSize +# define NSColor UIColor +# define NSImage UIImage +# define NSEvent UIEvent +# define NSWindow UIWindow +# define NSButton UIButton +# define NSApplication UIApplication +# define NSScreen UIScreen +#else +# import +# import +#endif + +@class ScreenSaverView; + +@interface SaverRunner : NSObject +{ + NSString *saverName; // the one currently loaded + NSArray *saverNames; // Names of available savers + NSString *saverDir; // Where we find saver bundles + +# ifndef USE_IPHONE + + NSBundle *saverBundle; + NSArray *windows; + IBOutlet NSMenu *menubar; + NSTimer *anim_timer; + +# else // USE_IPHONE + + ScreenSaverView *saverView; + UIView *backgroundView; + UINavigationController *rootViewController; + IBOutlet UIWindow *window; + EAGLContext *eagl_ctx; + GLuint gl_framebuffer, gl_renderbuffer; + IBOutlet UIView *view; + UIImage *saved_screenshot; + UIView *aboutBox; + NSTimer *splashTimer; + +# endif // USE_IPHONE +} + +- (void) loadSaver: (NSString *)name launch:(BOOL)launch; +- (void) loadSaver: (NSString *)name; +- (void) selectedSaverDidChange:(NSDictionary *)change; +- (void) aboutPanel: (id)sender; + +#ifndef USE_IPHONE +- (void) openPreferences: (id)sender; +#else // USE_IPHONE +- (void) openPreferences: (NSString *)which; +- (UIImage *) screenshot; +#endif // USE_IPHONE + +@end diff --git a/OSX/SaverRunner.icns b/OSX/SaverRunner.icns new file mode 100644 index 0000000000000000000000000000000000000000..0f052ae1bde28f2b299ddaa77c786f833a14a43d GIT binary patch literal 62554 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 literal 0 HcmV?d00001 diff --git a/OSX/SaverRunner.m b/OSX/SaverRunner.m new file mode 100644 index 00000000..4481bfce --- /dev/null +++ b/OSX/SaverRunner.m @@ -0,0 +1,1244 @@ +/* xscreensaver, Copyright (c) 2006-2013 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 program serves three purposes: + + First, It is a test harness for screen savers. When it launches, it + looks around for .saver bundles (in the current directory, and then in + the standard directories) and puts up a pair of windows that allow you + to select the saver to run. This is less clicking than running them + through System Preferences. This is the "SaverTester.app" program. + + Second, it can be used to transform any screen saver into a standalone + program. Just put one (and only one) .saver bundle into the app + bundle's Contents/Resources/ directory, and it will load and run that + saver at start-up (without the saver-selection menu or other chrome). + This is how the "Phosphor.app" and "Apple2.app" programs work. + + Third, it is the scaffolding which turns a set of screen savers into + a single iPhone / iPad program. In that case, all of the savers are + linked in to this executable, since iOS does not allow dynamic loading + of bundles that have executable code in them. Bleh. + */ + +#import +#import "SaverRunner.h" +#import "SaverListController.h" +#import "XScreenSaverGLView.h" +#import "yarandom.h" + +#ifdef USE_IPHONE + +@interface RotateyViewController : UINavigationController +@end + +@implementation RotateyViewController +- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o +{ + return YES; +} +@end + +#endif // USE_IPHONE + + +@implementation SaverRunner + + +- (ScreenSaverView *) makeSaverView: (NSString *) module + withSize: (NSSize) size +{ + Class new_class = 0; + +# ifndef USE_IPHONE + + // Load the XScreenSaverView subclass and code from a ".saver" bundle. + + NSString *name = [module stringByAppendingPathExtension:@"saver"]; + NSString *path = [saverDir stringByAppendingPathComponent:name]; + + if (! [[NSFileManager defaultManager] fileExistsAtPath:path]) { + NSLog(@"bundle \"%@\" does not exist", path); + return 0; + } + + NSLog(@"Loading %@", path); + + // NSBundle *obundle = saverBundle; + + saverBundle = [NSBundle bundleWithPath:path]; + if (saverBundle) + new_class = [saverBundle principalClass]; + + // Not entirely unsurprisingly, this tends to break the world. + // if (obundle && obundle != saverBundle) + // [obundle unload]; + +# else // USE_IPHONE + + // Determine whether to create an X11 view or an OpenGL view by + // looking for the "gl" tag in the xml file. This is kind of awful. + + NSString *path = [saverDir + stringByAppendingPathComponent: + [[[module lowercaseString] + stringByReplacingOccurrencesOfString:@" " + withString:@""] + stringByAppendingPathExtension:@"xml"]]; + NSData *xmld = [NSData dataWithContentsOfFile:path]; + NSAssert (xmld, @"no XML: %@", path); + NSString *xml = [XScreenSaverView decompressXML:xmld]; + Bool gl_p = (xml && [xml rangeOfString:@"gl=\"yes\""].length > 0); + + new_class = (gl_p + ? [XScreenSaverGLView class] + : [XScreenSaverView class]); + +# endif // USE_IPHONE + + if (! new_class) + return 0; + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = size.width; + rect.size.height = size.height; + + XScreenSaverView *instance = + [(XScreenSaverView *) [new_class alloc] + initWithFrame:rect + saverName:module + isPreview:YES]; + if (! instance) { + NSLog(@"Failed to instantiate %@ for \"%@\"", new_class, module); + return 0; + } + + + /* KLUGE: Inform the underlying program that we're in "standalone" + mode, e.g. running as "Phosphor.app" rather than "Phosphor.saver". + This is kind of horrible but I haven't thought of a more sensible + way to make this work. + */ +# ifndef USE_IPHONE + if ([saverNames count] == 1) { + putenv (strdup ("XSCREENSAVER_STANDALONE=1")); + } +# endif + + return (ScreenSaverView *) instance; +} + + +#ifndef USE_IPHONE + +static ScreenSaverView * +find_saverView_child (NSView *v) +{ + NSArray *kids = [v subviews]; + int nkids = [kids count]; + int i; + for (i = 0; i < nkids; i++) { + NSObject *kid = [kids objectAtIndex:i]; + if ([kid isKindOfClass:[ScreenSaverView class]]) { + return (ScreenSaverView *) kid; + } else { + ScreenSaverView *sv = find_saverView_child ((NSView *) kid); + if (sv) return sv; + } + } + return 0; +} + + +static ScreenSaverView * +find_saverView (NSView *v) +{ + while (1) { + NSView *p = [v superview]; + if (p) v = p; + else break; + } + return find_saverView_child (v); +} + + +/* Changes the contents of the menubar menus to correspond to + the running saver. Desktop only. + */ +static void +relabel_menus (NSObject *v, NSString *old_str, NSString *new_str) +{ + if ([v isKindOfClass:[NSMenu class]]) { + NSMenu *m = (NSMenu *)v; + [m setTitle: [[m title] stringByReplacingOccurrencesOfString:old_str + withString:new_str]]; + NSArray *kids = [m itemArray]; + int nkids = [kids count]; + int i; + for (i = 0; i < nkids; i++) { + relabel_menus ([kids objectAtIndex:i], old_str, new_str); + } + } else if ([v isKindOfClass:[NSMenuItem class]]) { + NSMenuItem *mi = (NSMenuItem *)v; + [mi setTitle: [[mi title] stringByReplacingOccurrencesOfString:old_str + withString:new_str]]; + NSMenu *m = [mi submenu]; + if (m) relabel_menus (m, old_str, new_str); + } +} + + +- (void) openPreferences: (id) sender +{ + ScreenSaverView *sv; + if ([sender isKindOfClass:[NSView class]]) { // Sent from button + sv = find_saverView ((NSView *) sender); + } else { + int i; + NSWindow *w = 0; + for (i = [windows count]-1; i >= 0; i--) { // Sent from menubar + w = [windows objectAtIndex:i]; + if ([w isKeyWindow]) break; + } + sv = find_saverView ([w contentView]); + } + + NSAssert (sv, @"no saver view"); + if (!sv) return; + 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 ([sv isAnimating]) + [sv stopAnimation]; + [sv startAnimation]; + } +} + + +- (void) preferencesClosed: (NSWindow *) sheet + returnCode: (int) returnCode + contextInfo: (void *) contextInfo +{ + [NSApp stopModalWithCode:returnCode]; +} + +#else // USE_IPHONE + + +- (UIImage *) screenshot +{ + return saved_screenshot; +} + +- (void) saveScreenshot +{ + // Most of this is from: + // http://developer.apple.com/library/ios/#qa/qa1703/_index.html + // The rotation stuff is by me. + + CGSize size = [[UIScreen mainScreen] bounds].size; + + UIInterfaceOrientation orient = + [[window rootViewController] interfaceOrientation]; + if (orient == UIInterfaceOrientationLandscapeLeft || + orient == UIInterfaceOrientationLandscapeRight) { + // Rotate the shape of the canvas 90 degrees. + double s = size.width; + size.width = size.height; + size.height = s; + } + + + // Create a graphics context with the target size + // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to + // take the scale into consideration + // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext + + if (UIGraphicsBeginImageContextWithOptions) + UIGraphicsBeginImageContextWithOptions (size, NO, 0); + else + UIGraphicsBeginImageContext (size); + + CGContextRef ctx = UIGraphicsGetCurrentContext(); + + + // Rotate the graphics context to match current hardware rotation. + // + switch (orient) { + case UIInterfaceOrientationPortraitUpsideDown: + CGContextTranslateCTM (ctx, [window center].x, [window center].y); + CGContextRotateCTM (ctx, M_PI); + CGContextTranslateCTM (ctx, -[window center].x, -[window center].y); + break; + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + CGContextTranslateCTM (ctx, + ([window frame].size.height - + [window frame].size.width) / 2, + ([window frame].size.width - + [window frame].size.height) / 2); + CGContextTranslateCTM (ctx, [window center].x, [window center].y); + CGContextRotateCTM (ctx, + (orient == UIInterfaceOrientationLandscapeLeft + ? M_PI/2 + : -M_PI/2)); + CGContextTranslateCTM (ctx, -[window center].x, -[window center].y); + break; + default: + break; + } + + // Iterate over every window from back to front + // + for (UIWindow *win in [[UIApplication sharedApplication] windows]) { + if (![win respondsToSelector:@selector(screen)] || + [win screen] == [UIScreen mainScreen]) { + + // -renderInContext: renders in the coordinate space of the layer, + // so we must first apply the layer's geometry to the graphics context + CGContextSaveGState (ctx); + + // Center the context around the window's anchor point + CGContextTranslateCTM (ctx, [win center].x, [win center].y); + + // Apply the window's transform about the anchor point + CGContextConcatCTM (ctx, [win transform]); + + // Offset by the portion of the bounds left of and above anchor point + CGContextTranslateCTM (ctx, + -[win bounds].size.width * [[win layer] anchorPoint].x, + -[win bounds].size.height * [[win layer] anchorPoint].y); + + // Render the layer hierarchy to the current context + [[win layer] renderInContext:ctx]; + + // Restore the context + CGContextRestoreGState (ctx); + } + } + + if (saved_screenshot) + [saved_screenshot release]; + saved_screenshot = [UIGraphicsGetImageFromCurrentImageContext() retain]; + + UIGraphicsEndImageContext(); +} + + +- (void) openPreferences: (NSString *) saver +{ + [self loadSaver:saver launch:NO]; + if (! saverView) return; + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + [prefs setObject:saver forKey:@"selectedSaverName"]; + [prefs synchronize]; + + [rootViewController pushViewController: [saverView configureView] + animated:YES]; +} + + +#endif // USE_IPHONE + + + +- (void)loadSaver:(NSString *)name launch:(BOOL)launch +{ +# ifndef USE_IPHONE + + if (saverName && [saverName isEqualToString: name]) { + if (launch) + for (NSWindow *win in windows) { + ScreenSaverView *sv = find_saverView ([win contentView]); + if (![sv isAnimating]) + [sv startAnimation]; + } + return; + } + + saverName = name; + + for (NSWindow *win in windows) { + NSView *cv = [win contentView]; + NSString *old_title = [win title]; + if (!old_title) old_title = @"XScreenSaver"; + [win setTitle: name]; + relabel_menus (menubar, old_title, name); + + ScreenSaverView *old_view = find_saverView (cv); + NSView *sup = old_view ? [old_view superview] : cv; + + if (old_view) { + if ([old_view isAnimating]) + [old_view stopAnimation]; + [old_view removeFromSuperview]; + } + + NSSize size = [cv frame].size; + ScreenSaverView *new_view = [self makeSaverView:name withSize: size]; + NSAssert (new_view, @"unable to make a saver view"); + + [new_view setFrame: (old_view ? [old_view frame] : [cv frame])]; + [sup addSubview: new_view]; + [win makeFirstResponder:new_view]; + [new_view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + [new_view retain]; + if (launch) + [new_view startAnimation]; + } + + NSUserDefaultsController *ctl = + [NSUserDefaultsController sharedUserDefaultsController]; + [ctl save:self]; + +# else // USE_IPHONE + +# if TARGET_IPHONE_SIMULATOR + NSLog (@"selecting saver \"%@\"", name); +# endif + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + [prefs setObject:name forKey:@"selectedSaverName"]; + [prefs synchronize]; + + if (saverName && [saverName isEqualToString: name]) { + if ([saverView isAnimating]) + return; + else + goto LAUNCH; + } + + saverName = name; + + if (! backgroundView) { + // This view is the parent of the XScreenSaverView, and exists only + // so that there is a black background behind it. Without this, when + // rotation is in progress, the scrolling-list window's corners show + // through in the corners. + backgroundView = [[[NSView class] alloc] initWithFrame:[window frame]]; + [backgroundView setBackgroundColor:[NSColor blackColor]]; + } + + if (saverView) { + if ([saverView isAnimating]) + [saverView stopAnimation]; + [saverView removeFromSuperview]; + [backgroundView removeFromSuperview]; + } + + NSSize size = [window frame].size; + saverView = [self makeSaverView:name withSize: size]; + + if (! saverView) { + [[[UIAlertView alloc] initWithTitle: name + message: @"Unable to load!" + delegate: nil + cancelButtonTitle: @"Bummer" + otherButtonTitles: nil] + show]; + return; + } + + [saverView setFrame: [window frame]]; + [saverView retain]; + [[NSNotificationCenter defaultCenter] + addObserver:saverView + selector:@selector(didRotate:) + name:UIDeviceOrientationDidChangeNotification object:nil]; + + LAUNCH: + if (launch) { + [self saveScreenshot]; + [window addSubview: backgroundView]; + [backgroundView addSubview: saverView]; + [saverView becomeFirstResponder]; + [saverView startAnimation]; + [self aboutPanel:nil]; + } +# endif // USE_IPHONE +} + + +- (void)loadSaver:(NSString *)name +{ + [self loadSaver:name launch:YES]; +} + + +- (void)aboutPanel:(id)sender +{ +# ifndef USE_IPHONE + + NSDictionary *bd = [saverBundle infoDictionary]; + NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:20]; + + [d setValue:[bd objectForKey:@"CFBundleName"] forKey:@"ApplicationName"]; + [d setValue:[bd objectForKey:@"CFBundleVersion"] forKey:@"Version"]; + [d setValue:[bd objectForKey:@"CFBundleShortVersionString"] + forKey:@"ApplicationVersion"]; + [d setValue:[bd objectForKey:@"NSHumanReadableCopyright"] forKey:@"Copy"]; + [d setValue:[[NSAttributedString alloc] + initWithString: (NSString *) + [bd objectForKey:@"CFBundleGetInfoString"]] + forKey:@"Credits"]; + + [[NSApplication sharedApplication] + orderFrontStandardAboutPanelWithOptions:d]; +# else // USE_IPHONE + + if ([saverNames count] == 1) + return; + + NSString *name = saverName; + NSString *year = [self makeDesc:saverName yearOnly:YES]; + + + CGRect frame = [saverView frame]; + CGFloat rot; + CGFloat pt1 = 24; + CGFloat pt2 = 14; + UIFont *font1 = [UIFont boldSystemFontOfSize: pt1]; + UIFont *font2 = [UIFont italicSystemFontOfSize:pt2]; + CGSize tsize1 = [name sizeWithFont:font1 + constrainedToSize:CGSizeMake(frame.size.width, + frame.size.height)]; + CGSize tsize2 = [year sizeWithFont:font2 + constrainedToSize:CGSizeMake(frame.size.width, + frame.size.height)]; + CGSize tsize = CGSizeMake (tsize1.width > tsize2.width ? + tsize1.width : tsize2.width, + tsize1.height + tsize2.height); + + // Don't know how to find inner margin of UITextView. + CGFloat margin = 10; + tsize.width += margin * 4; + tsize.height += margin * 2; + + if ([saverView frame].size.width >= 768) + tsize.height += pt1 * 3; // extra bottom margin on iPad + + frame = CGRectMake (0, 0, tsize.width, tsize.height); + + UIInterfaceOrientation orient = + // Why are both of these wrong when starting up rotated?? + [[UIDevice currentDevice] orientation]; + // [rootViewController interfaceOrientation]; + + /* Get the text oriented properly, and move it to the bottom of the + screen, since many savers have action in the middle. + */ + switch (orient) { + case UIDeviceOrientationLandscapeRight: + rot = -M_PI/2; + frame.origin.x = ([saverView frame].size.width + - (tsize.width - tsize.height) / 2 + - tsize.height); + frame.origin.y = ([saverView frame].size.height - tsize.height) / 2; + break; + case UIDeviceOrientationLandscapeLeft: + rot = M_PI/2; + frame.origin.x = -(tsize.width - tsize.height) / 2; + frame.origin.y = ([saverView frame].size.height - tsize.height) / 2; + break; + case UIDeviceOrientationPortraitUpsideDown: + rot = M_PI; + frame.origin.x = ([saverView frame].size.width - tsize.width) / 2; + frame.origin.y = 0; + break; + default: + rot = 0; + frame.origin.x = ([saverView frame].size.width - tsize.width) / 2; + frame.origin.y = [saverView frame].size.height - tsize.height; + break; + } + + if (aboutBox) + [aboutBox removeFromSuperview]; + + aboutBox = [[UIView alloc] initWithFrame:frame]; + + aboutBox.transform = CGAffineTransformMakeRotation (rot); + aboutBox.backgroundColor = [UIColor clearColor]; + + /* There seems to be no easy way to stroke the font, so instead draw + it 5 times, 4 in black and 1 in yellow, offset by 1 pixel, and add + a black shadow to each. (You'd think the shadow alone would be + enough, but there's no way to make it dark enough to be legible.) + */ + for (int i = 0; i < 5; i++) { + UITextView *textview; + int off = 1; + frame.origin.x = frame.origin.y = 0; + switch (i) { + case 0: frame.origin.x = -off; break; + case 1: frame.origin.x = off; break; + case 2: frame.origin.y = -off; break; + case 3: frame.origin.y = off; break; + } + + for (int j = 0; j < 2; j++) { + + frame.origin.y = (j == 0 ? 0 : pt1); + textview = [[UITextView alloc] initWithFrame:frame]; + textview.font = (j == 0 ? font1 : font2); + textview.text = (j == 0 ? name : year); + textview.textAlignment = UITextAlignmentCenter; + textview.showsHorizontalScrollIndicator = NO; + textview.showsVerticalScrollIndicator = NO; + textview.scrollEnabled = NO; + textview.editable = NO; + textview.userInteractionEnabled = NO; + textview.backgroundColor = [UIColor clearColor]; + textview.textColor = (i == 4 + ? [UIColor yellowColor] + : [UIColor blackColor]); + + CALayer *textLayer = (CALayer *) + [textview.layer.sublayers objectAtIndex:0]; + textLayer.shadowColor = [UIColor blackColor].CGColor; + textLayer.shadowOffset = CGSizeMake(0, 0); + textLayer.shadowOpacity = 1; + textLayer.shadowRadius = 2; + + [aboutBox addSubview:textview]; + } + } + + CABasicAnimation *anim = + [CABasicAnimation animationWithKeyPath:@"opacity"]; + anim.duration = 0.3; + anim.repeatCount = 1; + anim.autoreverses = NO; + anim.fromValue = [NSNumber numberWithFloat:0.0]; + anim.toValue = [NSNumber numberWithFloat:1.0]; + [aboutBox.layer addAnimation:anim forKey:@"animateOpacity"]; + + [backgroundView addSubview:aboutBox]; + + if (splashTimer) + [splashTimer invalidate]; + + splashTimer = + [NSTimer scheduledTimerWithTimeInterval: anim.duration + 2 + target:self + selector:@selector(aboutOff) + userInfo:nil + repeats:NO]; +# endif // USE_IPHONE +} + + +# ifdef USE_IPHONE +- (void)aboutOff +{ + if (aboutBox) { + if (splashTimer) { + [splashTimer invalidate]; + splashTimer = 0; + } + CABasicAnimation *anim = + [CABasicAnimation animationWithKeyPath:@"opacity"]; + anim.duration = 0.3; + anim.repeatCount = 1; + anim.autoreverses = NO; + anim.fromValue = [NSNumber numberWithFloat: 1]; + anim.toValue = [NSNumber numberWithFloat: 0]; + anim.delegate = self; + aboutBox.layer.opacity = 0; + [aboutBox.layer addAnimation:anim forKey:@"animateOpacity"]; + } +} +#endif // USE_IPHONE + + + +- (void)selectedSaverDidChange:(NSDictionary *)change +{ + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + NSString *name = [prefs stringForKey:@"selectedSaverName"]; + + if (! name) return; + + if (! [saverNames containsObject:name]) { + NSLog (@"saver \"%@\" does not exist", name); + return; + } + + [self loadSaver: name]; +} + + +- (NSArray *) listSaverBundleNamesInDir:(NSString *)dir +{ +# ifndef USE_IPHONE + NSString *ext = @"saver"; +# else + NSString *ext = @"xml"; +# endif + + NSArray *files = [[NSFileManager defaultManager] + contentsOfDirectoryAtPath:dir error:nil]; + if (! files) return 0; + NSMutableArray *result = [NSMutableArray arrayWithCapacity: [files count]+1]; + + for (NSString *p in files) { + if ([[p pathExtension] caseInsensitiveCompare: ext]) + continue; + + NSString *name = [[p lastPathComponent] stringByDeletingPathExtension]; + +# ifdef USE_IPHONE + // Get the saver name's capitalization right by reading the XML file. + + p = [dir stringByAppendingPathComponent: p]; + NSData *xmld = [NSData dataWithContentsOfFile:p]; + NSAssert (xmld, @"no XML: %@", p); + NSString *xml = [XScreenSaverView decompressXML:xmld]; + NSRange r = [xml rangeOfString:@"_label=\"" options:0]; + NSAssert1 (r.length, @"no name in %@", p); + if (r.length) { + xml = [xml substringFromIndex: r.location + r.length]; + r = [xml rangeOfString:@"\"" options:0]; + if (r.length) name = [xml substringToIndex: r.location]; + } + +# endif // USE_IPHONE + + NSAssert1 (name, @"no name in %@", p); + if (name) [result addObject: name]; + } + + if (! [result count]) + result = 0; + + return result; +} + + + +- (NSArray *) listSaverBundleNames +{ + NSMutableArray *dirs = [NSMutableArray arrayWithCapacity: 10]; + +# ifndef USE_IPHONE + // On MacOS, look in the "Contents/Resources/" and "Contents/PlugIns/" + // directories in the bundle. + [dirs addObject: [[[[NSBundle mainBundle] bundlePath] + stringByAppendingPathComponent:@"Contents"] + stringByAppendingPathComponent:@"Resources"]]; + [dirs addObject: [[NSBundle mainBundle] builtInPlugInsPath]]; + + // Also look in the same directory as the executable. + [dirs addObject: [[[NSBundle mainBundle] bundlePath] + stringByDeletingLastPathComponent]]; + + // Finally, look in standard MacOS screensaver directories. +// [dirs addObject: @"~/Library/Screen Savers"]; +// [dirs addObject: @"/Library/Screen Savers"]; +// [dirs addObject: @"/System/Library/Screen Savers"]; + +# else // USE_IPHONE + + // On iOS, only look in the bundle's root directory. + [dirs addObject: [[NSBundle mainBundle] bundlePath]]; + +# endif // USE_IPHONE + + int i; + for (i = 0; i < [dirs count]; i++) { + NSString *dir = [dirs objectAtIndex:i]; + NSArray *names = [self listSaverBundleNamesInDir:dir]; + if (! names) continue; + saverDir = [dir retain]; + saverNames = [names retain]; + return names; + } + + NSString *err = @"no .saver bundles found in: "; + for (i = 0; i < [dirs count]; i++) { + if (i) err = [err stringByAppendingString:@", "]; + err = [err stringByAppendingString:[[dirs objectAtIndex:i] + stringByAbbreviatingWithTildeInPath]]; + err = [err stringByAppendingString:@"/"]; + } + NSLog (@"%@", err); + return [NSArray array]; +} + + +/* Create the popup menu of available saver names. + */ +#ifndef USE_IPHONE + +- (NSPopUpButton *) makeMenu +{ + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = 10; + rect.size.height = 10; + NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame:rect + pullsDown:NO]; + int i; + float max_width = 0; + for (i = 0; i < [saverNames count]; i++) { + NSString *name = [saverNames objectAtIndex:i]; + [popup addItemWithTitle:name]; + [[popup itemWithTitle:name] setRepresentedObject:name]; + [popup sizeToFit]; + NSRect r = [popup frame]; + if (r.size.width > max_width) max_width = r.size.width; + } + + // Bind the menu to preferences, and trigger a callback when an item + // is selected. + // + NSString *key = @"values.selectedSaverName"; + NSUserDefaultsController *prefs = + [NSUserDefaultsController sharedUserDefaultsController]; + [prefs addObserver:self + forKeyPath:key + options:0 + context:@selector(selectedSaverDidChange:)]; + [popup bind:@"selectedObject" + toObject:prefs + withKeyPath:key + options:nil]; + [prefs setAppliesImmediately:YES]; + + NSRect r = [popup frame]; + r.size.width = max_width; + [popup setFrame:r]; + return popup; +} + +#else // USE_IPHONE + +- (NSString *) makeDesc:(NSString *)saver + yearOnly:(BOOL) yearp +{ + NSString *desc = 0; + NSString *path = [saverDir stringByAppendingPathComponent: + [[saver lowercaseString] + stringByReplacingOccurrencesOfString:@" " + withString:@""]]; + NSRange r; + + path = [path stringByAppendingPathExtension:@"xml"]; + NSData *xmld = [NSData dataWithContentsOfFile:path]; + if (! xmld) goto FAIL; + desc = [XScreenSaverView decompressXML:xmld]; + if (! desc) goto FAIL; + + r = [desc rangeOfString:@"<_description>" + options:NSCaseInsensitiveSearch]; + if (r.length == 0) { + desc = 0; + goto FAIL; + } + desc = [desc substringFromIndex: r.location + r.length]; + r = [desc rangeOfString:@"" + options:NSCaseInsensitiveSearch]; + if (r.length > 0) + desc = [desc substringToIndex: r.location]; + + // Leading and trailing whitespace. + desc = [desc stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + // Let's see if we can find a year on the last line. + r = [desc rangeOfString:@"\n" options:NSBackwardsSearch]; + NSString *year = 0; + for (NSString *word in + [[desc substringFromIndex:r.location + r.length] + componentsSeparatedByCharactersInSet: + [NSCharacterSet characterSetWithCharactersInString: + @" \t\n-."]]) { + int n = [word doubleValue]; + if (n > 1970 && n < 2100) + year = word; + } + + // Delete everything after the first blank line. + r = [desc rangeOfString:@"\n\n" options:0]; + if (r.length > 0) + desc = [desc substringToIndex: r.location]; + + // Truncate really long ones. + int max = 140; + if ([desc length] > max) + desc = [desc substringToIndex: max]; + + if (year) + desc = [year stringByAppendingString: + [@": " stringByAppendingString: desc]]; + + if (yearp) + desc = year ? year : @""; + +FAIL: + if (! desc) { + if ([saverNames count] > 1) + desc = @"Oops, this module appears to be incomplete."; + else + desc = @""; + } + + return desc; +} + +- (NSString *) makeDesc:(NSString *)saver +{ + return [self makeDesc:saver yearOnly:NO]; +} + + + +/* Create a dictionary of one-line descriptions of every saver, + for display on the UITableView. + */ +- (NSDictionary *)makeDescTable +{ + NSMutableDictionary *dict = + [NSMutableDictionary dictionaryWithCapacity:[saverNames count]]; + for (NSString *saver in saverNames) { + [dict setObject:[self makeDesc:saver] forKey:saver]; + } + return dict; +} + + +#endif // USE_IPHONE + + + +/* This is called when the "selectedSaverName" pref changes, e.g., + when a menu selection is made. + */ +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context +{ + SEL dispatchSelector = (SEL)context; + if (dispatchSelector != NULL) { + [self performSelector:dispatchSelector withObject:change]; + } else { + [super observeValueForKeyPath:keyPath + ofObject:object + change:change + context:context]; + } +} + + +# ifndef USE_IPHONE + +/* Create the desktop window shell, possibly including a preferences button. + */ +- (NSWindow *) makeWindow +{ + NSRect rect; + static int count = 0; + Bool simple_p = ([saverNames count] == 1); + NSButton *pb = 0; + NSPopUpButton *menu = 0; + NSBox *gbox = 0; + NSBox *pbox = 0; + + NSRect sv_rect; + sv_rect.origin.x = sv_rect.origin.y = 0; + sv_rect.size.width = 320; + sv_rect.size.height = 240; + ScreenSaverView *sv = [[ScreenSaverView alloc] // dummy placeholder + initWithFrame:sv_rect + isPreview:YES]; + + // make a "Preferences" button + // + if (! simple_p) { + rect.origin.x = 0; + rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + 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]; + [pb setAction:@selector(openPreferences:)]; + + // Make a saver selection menu + // + menu = [self makeMenu]; + rect.origin.x = 2; + rect.origin.y = 2; + [menu setFrameOrigin:rect.origin]; + + // 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; + 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; + pbox = [[NSBox alloc] initWithFrame:rect]; + [pbox setTitlePosition:NSNoTitle]; + [pbox setBorderType:NSNoBorder]; + [pbox addSubview:gbox]; + if (menu) [pbox addSubview:menu]; + if (pb) [pbox addSubview:pb]; + [pbox sizeToFit]; + + [pb setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; + [menu setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; + [gbox setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + [pbox setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + } + + [sv setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + + + // and make a window to hold that. + // + NSScreen *screen = [NSScreen mainScreen]; + rect = pbox ? [pbox frame] : [sv 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 * (count ? 0.55 : -0.55); + + NSWindow *win = [[NSWindow alloc] + initWithContentRect:rect + styleMask:(NSTitledWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask) + backing:NSBackingStoreBuffered + defer:YES + screen:screen]; + [win setMinSize:[win frameRectForContentRect:rect].size]; + [[win contentView] addSubview: (pbox ? (NSView *) pbox : (NSView *) sv)]; + + [win makeKeyAndOrderFront:win]; + + [sv startAnimation]; // this is the dummy saver + + count++; + + return win; +} + + +- (void) animTimer +{ + for (NSWindow *win in windows) { + ScreenSaverView *sv = find_saverView ([win contentView]); + if ([sv isAnimating]) + [sv animateOneFrame]; + } +} + +# endif // !USE_IPHONE + + +- (void)applicationDidFinishLaunching: +# ifndef USE_IPHONE + (NSNotification *) notif +# else // USE_IPHONE + (UIApplication *) application +# endif // USE_IPHONE +{ + [self listSaverBundleNames]; + +# ifndef USE_IPHONE + int window_count = ([saverNames count] <= 1 ? 1 : 2); + NSMutableArray *a = [[NSMutableArray arrayWithCapacity: window_count+1] + retain]; + windows = a; + + int i; + // Create either one window (for standalone, e.g. Phosphor.app) + // or two windows for SaverTester.app. + for (i = 0; i < window_count; i++) { + NSWindow *win = [self makeWindow]; + // Get the last-saved window position out of preferences. + [win setFrameAutosaveName: + [NSString stringWithFormat:@"XScreenSaverWindow%d", i]]; + [win setFrameUsingName:[win frameAutosaveName]]; + [a addObject: win]; + // This prevents clicks from being seen by savers. + // [win setMovableByWindowBackground:YES]; + } +# else // USE_IPHONE + +# undef ya_rand_init + ya_rand_init (0); // Now's a good time. + + rootViewController = [[[RotateyViewController alloc] init] retain]; + [window setRootViewController: rootViewController]; + + SaverListController *menu = [[SaverListController alloc] + initWithNames:saverNames + descriptions:[self makeDescTable]]; + [rootViewController pushViewController:menu animated:YES]; + [menu becomeFirstResponder]; + + [window makeKeyAndVisible]; + [window setAutoresizesSubviews:YES]; + [window setAutoresizingMask: + (UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight)]; + + application.applicationSupportsShakeToEdit = YES; + +# endif // USE_IPHONE + + NSString *forced = 0; + /* In the XCode project, each .saver scheme sets this env var when + launching SaverTester.app so that it knows which one we are + currently debugging. If this is set, it overrides the default + selection in the popup menu. If unset, that menu persists to + whatever it was last time. + */ + const char *f = getenv ("SELECTED_SAVER"); + if (f && *f) + forced = [NSString stringWithCString:(char *)f + encoding:NSUTF8StringEncoding]; + + if (forced && ![saverNames containsObject:forced]) { + NSLog(@"forced saver \"%@\" does not exist", forced); + forced = 0; + } + + // If there's only one saver, run that. + if (!forced && [saverNames count] == 1) + forced = [saverNames objectAtIndex:0]; + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; + +# ifdef USE_IPHONE + NSString *prev = [prefs stringForKey:@"selectedSaverName"]; + + if (forced) + prev = forced; + + // If nothing was selected (e.g., this is the first launch) + // then scroll randomly instead of starting up at "A". + // + if (!prev) + prev = [saverNames objectAtIndex: (random() % [saverNames count])]; + + if (prev) + [menu scrollTo: prev]; +# endif // USE_IPHONE + + if (forced) + [prefs setObject:forced forKey:@"selectedSaverName"]; + +# ifdef USE_IPHONE + /* Don't auto-launch the saver unless it was running last time. + XScreenSaverView manages this, on crash_timer. + Unless forced. + */ + if (!forced && ![prefs boolForKey:@"wasRunning"]) + return; +# endif + + [self selectedSaverDidChange:nil]; + + +# ifndef USE_IPHONE + /* On 10.8 and earlier, [ScreenSaverView startAnimation] causes the + ScreenSaverView to run its own timer calling animateOneFrame. + On 10.9, that fails because the private class ScreenSaverModule + is only initialized properly by ScreenSaverEngine, and in the + context of SaverRunner, the null ScreenSaverEngine instance + behaves as if [ScreenSaverEngine needsAnimationTimer] returned false. + So, if it looks like this is the 10.9 version of ScreenSaverModule + instead of the 10.8 version, we run our own timer here. This sucks. + */ + if (!anim_timer) { + Class ssm = NSClassFromString (@"ScreenSaverModule"); + if (ssm && [ssm instancesRespondToSelector: + @selector(needsAnimationTimer)]) { + NSWindow *win = [windows objectAtIndex:0]; + ScreenSaverView *sv = find_saverView ([win contentView]); + anim_timer = [NSTimer scheduledTimerWithTimeInterval: + [sv animationTimeInterval] + target:self + selector:@selector(animTimer) + userInfo:nil + repeats:YES]; + } + } +# endif // !USE_IPHONE +} + + +#ifndef USE_IPHONE + +/* When the window closes, exit (even if prefs still open.) + */ +- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *) n +{ + return YES; +} + +# else // USE_IPHONE + +- (void)applicationWillResignActive:(UIApplication *)app +{ + [(XScreenSaverView *)view setScreenLocked:YES]; +} + +- (void)applicationDidBecomeActive:(UIApplication *)app +{ + [(XScreenSaverView *)view setScreenLocked:NO]; +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + [(XScreenSaverView *)view setScreenLocked:YES]; +} + +#endif // USE_IPHONE + + +@end diff --git a/OSX/SaverRunner.plist b/OSX/SaverRunner.plist new file mode 100644 index 00000000..fc1e334d --- /dev/null +++ b/OSX/SaverRunner.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleGetInfoString + 5.26 + CFBundleIconFile + SaverRunner + CFBundleIdentifier + ${BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + 5.26 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 5.26 + CFBundleSignature + ???? + CFBundleVersion + 5.26 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + 5.26 + NSMainNibFile + SaverRunner + NSPrincipalClass + NSApplication + + diff --git a/OSX/Sparkle.framework/Headers b/OSX/Sparkle.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/OSX/Sparkle.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/OSX/Sparkle.framework/Resources b/OSX/Sparkle.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/OSX/Sparkle.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/OSX/Sparkle.framework/Sparkle b/OSX/Sparkle.framework/Sparkle new file mode 120000 index 00000000..b2c52731 --- /dev/null +++ b/OSX/Sparkle.framework/Sparkle @@ -0,0 +1 @@ +Versions/Current/Sparkle \ No newline at end of file diff --git a/OSX/Sparkle.framework/Versions/A/Headers/SUAppcast.h b/OSX/Sparkle.framework/Versions/A/Headers/SUAppcast.h new file mode 100755 index 00000000..5a60d2fd --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Headers/SUAppcast.h @@ -0,0 +1,36 @@ +// +// SUAppcast.h +// Sparkle +// +// Created by Andy Matuschak on 3/12/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUAPPCAST_H +#define SUAPPCAST_H + +@class SUAppcastItem; +@interface SUAppcast : NSObject +{ +@private + NSArray *items; + NSString *userAgentString; + id delegate; + NSString *downloadFilename; + NSURLDownload *download; +} + +- (void)fetchAppcastFromURL:(NSURL *)url; +- (void)setDelegate:delegate; +- (void)setUserAgentString:(NSString *)userAgentString; + +- (NSArray *)items; + +@end + +@interface NSObject (SUAppcastDelegate) +- (void)appcastDidFinishLoading:(SUAppcast *)appcast; +- (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; +@end + +#endif diff --git a/OSX/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h b/OSX/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h new file mode 100755 index 00000000..d6f9c64f --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h @@ -0,0 +1,60 @@ +// +// SUAppcastItem.h +// Sparkle +// +// Created by Andy Matuschak on 3/12/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUAPPCASTITEM_H +#define SUAPPCASTITEM_H + +@interface SUAppcastItem : NSObject +{ +@private + NSString *title; + NSDate *date; + NSString *itemDescription; + + NSURL *releaseNotesURL; + + NSString *DSASignature; + NSString *minimumSystemVersion; + NSString *maximumSystemVersion; + + NSURL *fileURL; + NSString *versionString; + NSString *displayVersionString; + + NSDictionary *deltaUpdates; + + NSDictionary *propertiesDictionary; + + NSURL *infoURL; // UK 2007-08-31 +} + +// Initializes with data from a dictionary provided by the RSS class. +- initWithDictionary:(NSDictionary *)dict; +- initWithDictionary:(NSDictionary *)dict failureReason:(NSString**)error; + +- (NSString *)title; +- (NSString *)versionString; +- (NSString *)displayVersionString; +- (NSDate *)date; +- (NSString *)itemDescription; +- (NSURL *)releaseNotesURL; +- (NSURL *)fileURL; +- (NSString *)DSASignature; +- (NSString *)minimumSystemVersion; +- (NSString *)maximumSystemVersion; +- (NSDictionary *)deltaUpdates; +- (BOOL)isDeltaUpdate; + +// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. +- (NSDictionary *)propertiesDictionary; + +- (NSURL *)infoURL; // UK 2007-08-31 + +@end + +#endif diff --git a/OSX/Sparkle.framework/Versions/A/Headers/SUUpdater.h b/OSX/Sparkle.framework/Versions/A/Headers/SUUpdater.h new file mode 100755 index 00000000..cd795667 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Headers/SUUpdater.h @@ -0,0 +1,161 @@ +// +// SUUpdater.h +// Sparkle +// +// Created by Andy Matuschak on 1/4/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUUPDATER_H +#define SUUPDATER_H + +#import "SUVersionComparisonProtocol.h" +#import "SUVersionDisplayProtocol.h" + +@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; + +@interface SUUpdater : NSObject +{ +@private + NSTimer *checkTimer; + SUUpdateDriver *driver; + + NSString *customUserAgentString; + SUHost *host; + IBOutlet id delegate; +} + ++ (SUUpdater *)sharedUpdater; ++ (SUUpdater *)updaterForBundle:(NSBundle *)bundle; +- (id)initForBundle:(NSBundle *)bundle; + +- (NSBundle *)hostBundle; + +- (void)setDelegate:(id)delegate; +- (id)delegate; + +- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; +- (BOOL)automaticallyChecksForUpdates; + +- (void)setUpdateCheckInterval:(NSTimeInterval)interval; +- (NSTimeInterval)updateCheckInterval; + +- (void)setFeedURL:(NSURL *)feedURL; +- (NSURL *)feedURL; // *** MUST BE CALLED ON MAIN THREAD *** + +- (void)setUserAgentString:(NSString *)userAgent; +- (NSString *)userAgentString; + +- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; +- (BOOL)sendsSystemProfile; + +- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; +- (BOOL)automaticallyDownloadsUpdates; + +// This IBAction is meant for a main menu item. Hook up any menu item to this action, +// and Sparkle will check for updates and report back its findings verbosely. +- (IBAction)checkForUpdates:(id)sender; + +// This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update, +// in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an +// update is found, it will be downloaded and prepped for installation. +- (void)checkForUpdatesInBackground; + +// Date of last update check. Returns nil if no check has been performed. +- (NSDate*)lastUpdateCheckDate; + +// This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though, +// (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. +- (void)checkForUpdateInformation; + +// Call this to appropriately schedule or cancel the update checking timer according to the preferences for time interval and automatic checks. This call does not change the date of the next check, but only the internal NSTimer. +- (void)resetUpdateCycle; + +- (BOOL)updateInProgress; + +@end + + +// ----------------------------------------------------------------------------- +// SUUpdater Delegate: +// ----------------------------------------------------------------------------- + +@interface NSObject (SUUpdaterDelegateInformalProtocol) + +// Use this to keep Sparkle from popping up e.g. while your setup assistant is showing: +- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)bundle; + +// This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. +- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; + +// Override this to dynamically specify the entire URL. +- (NSString*)feedURLStringForUpdater:(SUUpdater*)updater; + +// Use this to override the default behavior for Sparkle prompting the user about automatic update checks. +- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; + +// Implement this if you want to do some special handling with the appcast once it finishes loading. +- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; + +// If you're using special logic or extensions in your appcast, implement this to use your own logic for finding +// a valid update, if any, in the given appcast. +- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle; + +// Sent when a valid update is found by the update driver. +- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; + +// Sent when a valid update is not found. +- (void)updaterDidNotFindUpdate:(SUUpdater *)update; + +// Sent immediately before installing the specified update. +- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; + +// Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. +// This is not called if the user didn't relaunch on the previous update, in that case it will immediately +// restart. +- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; + +// Some apps *can not* be relaunched in certain circumstances. They can use this method +// to prevent a relaunch "hard": +- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater; + +// Called immediately before relaunching. +- (void)updaterWillRelaunchApplication:(SUUpdater *)updater; + +// This method allows you to provide a custom version comparator. +// If you don't implement this method or return nil, the standard version comparator will be used. +- (id )versionComparatorForUpdater:(SUUpdater *)updater; + +// This method allows you to provide a custom version comparator. +// If you don't implement this method or return nil, the standard version displayer will be used. +- (id )versionDisplayerForUpdater:(SUUpdater *)updater; + +// Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle. +- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; + +// Called before and after, respectively, an updater shows a modal alert window, to give the host +// the opportunity to hide attached windows etc. that may get in the way: +-(void) updaterWillShowModalAlert:(SUUpdater *)updater; +-(void) updaterDidShowModalAlert:(SUUpdater *)updater; + +@end + + +// ----------------------------------------------------------------------------- +// Constants: +// ----------------------------------------------------------------------------- + +// Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. +#if defined(DEBUG) && DEBUG && 0 +#define SU_MIN_CHECK_INTERVAL 60 +#else +#define SU_MIN_CHECK_INTERVAL 60*60 +#endif + +#if defined(DEBUG) && DEBUG && 0 +#define SU_DEFAULT_CHECK_INTERVAL 60 +#else +#define SU_DEFAULT_CHECK_INTERVAL 60*60*24 +#endif + +#endif diff --git a/OSX/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h b/OSX/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h new file mode 100755 index 00000000..6c65ea45 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h @@ -0,0 +1,29 @@ +// +// SUVersionComparisonProtocol.h +// Sparkle +// +// Created by Andy Matuschak on 12/21/07. +// Copyright 2007 Andy Matuschak. All rights reserved. +// + +#ifndef SUVERSIONCOMPARISONPROTOCOL_H +#define SUVERSIONCOMPARISONPROTOCOL_H + +#import + +/*! + @protocol + @abstract Implement this protocol to provide version comparison facilities for Sparkle. +*/ +@protocol SUVersionComparison + +/*! + @method + @abstract An abstract method to compare two version strings. + @discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent. +*/ +- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! + +@end + +#endif diff --git a/OSX/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h b/OSX/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h new file mode 100755 index 00000000..368b9c9f --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h @@ -0,0 +1,27 @@ +// +// SUVersionDisplayProtocol.h +// EyeTV +// +// Created by Uli Kusterer on 08.12.09. +// Copyright 2009 Elgato Systems GmbH. All rights reserved. +// + +#import + + +/*! + @protocol + @abstract Implement this protocol to apply special formatting to the two + version numbers. +*/ +@protocol SUVersionDisplay + +/*! + @method + @abstract An abstract method to format two version strings. + @discussion You get both so you can display important distinguishing + information, but leave out unnecessary/confusing parts. +*/ +-(void) formatVersion: (NSString**)inOutVersionA andVersion: (NSString**)inOutVersionB; + +@end diff --git a/OSX/Sparkle.framework/Versions/A/Headers/Sparkle.h b/OSX/Sparkle.framework/Versions/A/Headers/Sparkle.h new file mode 100755 index 00000000..08dd5777 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Headers/Sparkle.h @@ -0,0 +1,21 @@ +// +// Sparkle.h +// Sparkle +// +// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SPARKLE_H +#define SPARKLE_H + +// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless +// there are name-space collisions) so we can list all of them to start with: + +#import + +#import +#import +#import + +#endif diff --git a/OSX/Sparkle.framework/Versions/A/Resources/Info.plist b/OSX/Sparkle.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..1e79abe6 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,40 @@ + + + + + BuildMachineOSBuild + 13A603 + CFBundleDevelopmentRegion + en + CFBundleExecutable + Sparkle + CFBundleIdentifier + org.andymatuschak.Sparkle + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Sparkle + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.5 Beta (git) + CFBundleSignature + ???? + CFBundleVersion + 1.5 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 5A3005 + DTPlatformVersion + GM + DTSDKBuild + 13A595 + DTSDKName + macosx10.9 + DTXcode + 0502 + DTXcodeBuild + 5A3005 + + diff --git a/OSX/Sparkle.framework/Versions/A/Resources/License.txt b/OSX/Sparkle.framework/Versions/A/Resources/License.txt new file mode 100755 index 00000000..08364c63 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/License.txt @@ -0,0 +1,38 @@ +Copyright (c) 2006 Andy Matuschak + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +================= +EXTERNAL LICENSES +================= + +License for bspatch.c and bsdiff.c, from bsdiff 4.3 (: +/*- + * Copyright 2003-2005 Colin Percival + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/OSX/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist b/OSX/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist new file mode 100755 index 00000000..63644f08 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist @@ -0,0 +1,182 @@ + + + + + ADP2,1 + Developer Transition Kit + iMac1,1 + iMac G3 (Rev A-D) + iMac4,1 + iMac (Core Duo) + iMac4,2 + iMac for Education (17-inch, Core Duo) + iMac5,1 + iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) + iMac5,2 + iMac (Core 2 Duo, 17 inch, Combo Drive) + iMac6,1 + iMac (Core 2 Duo, 24 inch, SuperDrive) + iMac8,1 + iMac (April 2008) + MacBook1,1 + MacBook (Core Duo) + MacBook2,1 + MacBook (Core 2 Duo) + MacBook4,1 + MacBook (Core 2 Duo Feb 2008) + MacBookAir1,1 + MacBook Air (January 2008) + MacBookAir2,1 + MacBook Air (June 2009) + MacBookAir3,1 + MacBook Air (October 2010) + MacBookPro1,1 + MacBook Pro Core Duo (15-inch) + MacBookPro1,2 + MacBook Pro Core Duo (17-inch) + MacBookPro2,1 + MacBook Pro Core 2 Duo (17-inch) + MacBookPro2,2 + MacBook Pro Core 2 Duo (15-inch) + MacBookPro3,1 + MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) + MacBookPro3,2 + MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) + MacBookPro4,1 + MacBook Pro (Core 2 Duo Feb 2008) + Macmini1,1 + Mac Mini (Core Solo/Duo) + MacPro1,1 + Mac Pro (four-core) + MacPro2,1 + Mac Pro (eight-core) + MacPro3,1 + Mac Pro (January 2008 4- or 8- core "Harpertown") + MacPro4,1 + Mac Pro (March 2009) + MacPro5,1 + Mac Pro (August 2010) + PowerBook1,1 + PowerBook G3 + PowerBook2,1 + iBook G3 + PowerBook2,2 + iBook G3 (FireWire) + PowerBook2,3 + iBook G3 + PowerBook2,4 + iBook G3 + PowerBook3,1 + PowerBook G3 (FireWire) + PowerBook3,2 + PowerBook G4 + PowerBook3,3 + PowerBook G4 (Gigabit Ethernet) + PowerBook3,4 + PowerBook G4 (DVI) + PowerBook3,5 + PowerBook G4 (1GHz / 867MHz) + PowerBook4,1 + iBook G3 (Dual USB, Late 2001) + PowerBook4,2 + iBook G3 (16MB VRAM) + PowerBook4,3 + iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) + PowerBook5,1 + PowerBook G4 (17 inch) + PowerBook5,2 + PowerBook G4 (15 inch FW 800) + PowerBook5,3 + PowerBook G4 (17-inch 1.33GHz) + PowerBook5,4 + PowerBook G4 (15 inch 1.5/1.33GHz) + PowerBook5,5 + PowerBook G4 (17-inch 1.5GHz) + PowerBook5,6 + PowerBook G4 (15 inch 1.67GHz/1.5GHz) + PowerBook5,7 + PowerBook G4 (17-inch 1.67GHz) + PowerBook5,8 + PowerBook G4 (Double layer SD, 15 inch) + PowerBook5,9 + PowerBook G4 (Double layer SD, 17 inch) + PowerBook6,1 + PowerBook G4 (12 inch) + PowerBook6,2 + PowerBook G4 (12 inch, DVI) + PowerBook6,3 + iBook G4 + PowerBook6,4 + PowerBook G4 (12 inch 1.33GHz) + PowerBook6,5 + iBook G4 (Early-Late 2004) + PowerBook6,7 + iBook G4 (Mid 2005) + PowerBook6,8 + PowerBook G4 (12 inch 1.5GHz) + PowerMac1,1 + Power Macintosh G3 (Blue & White) + PowerMac1,2 + Power Macintosh G4 (PCI Graphics) + PowerMac10,1 + Mac Mini G4 + PowerMac10,2 + Mac Mini (Late 2005) + PowerMac11,2 + Power Macintosh G5 (Late 2005) + PowerMac12,1 + iMac G5 (iSight) + PowerMac2,1 + iMac G3 (Slot-loading CD-ROM) + PowerMac2,2 + iMac G3 (Summer 2000) + PowerMac3,1 + Power Macintosh G4 (AGP Graphics) + PowerMac3,2 + Power Macintosh G4 (AGP Graphics) + PowerMac3,3 + Power Macintosh G4 (Gigabit Ethernet) + PowerMac3,4 + Power Macintosh G4 (Digital Audio) + PowerMac3,5 + Power Macintosh G4 (Quick Silver) + PowerMac3,6 + Power Macintosh G4 (Mirrored Drive Door) + PowerMac4,1 + iMac G3 (Early/Summer 2001) + PowerMac4,2 + iMac G4 (Flat Panel) + PowerMac4,4 + eMac + PowerMac4,5 + iMac G4 (17-inch Flat Panel) + PowerMac5,1 + Power Macintosh G4 Cube + PowerMac6,1 + iMac G4 (USB 2.0) + PowerMac6,3 + iMac G4 (20-inch Flat Panel) + PowerMac6,4 + eMac (USB 2.0, 2005) + PowerMac7,2 + Power Macintosh G5 + PowerMac7,3 + Power Macintosh G5 + PowerMac8,1 + iMac G5 + PowerMac8,2 + iMac G5 (Ambient Light Sensor) + PowerMac9,1 + Power Macintosh G5 (Late 2005) + RackMac1,1 + Xserve G4 + RackMac1,2 + Xserve G4 (slot-loading, cluster node) + RackMac3,1 + Xserve G5 + Xserve1,1 + Xserve (Intel Xeon) + Xserve2,1 + Xserve (January 2008 quad-core) + + diff --git a/OSX/Sparkle.framework/Versions/A/Resources/SUStatus.nib b/OSX/Sparkle.framework/Versions/A/Resources/SUStatus.nib new file mode 100644 index 0000000000000000000000000000000000000000..356987eb973cec5c23bd2e40fecfe5732fe621ec GIT binary patch literal 6565 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 I{a-ooU;Q_Y@&Et; literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..2d1b77b9e97298e0c7710433490cbb309215b3e4 GIT binary patch literal 7118 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..b8925e776deab3120aca32d87dbaafa2be8affd6 GIT binary patch literal 10445 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 z@icm7d732)W2688 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..006d6aa4409b16173ea1af965a298d6741ad2930 GIT binary patch literal 12737 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..335264f91d38f0b41679f03d43f26d89fbe6cbdc GIT binary patch literal 7039 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 E07LU7umAu6 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..fe70bf25b79fb69c9053dcbe4e249318a55e04f7 GIT binary patch literal 10241 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 WI~Ka!@Ph82^r8pk&%|G^@BaYoltdW- literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..9dcd9442d11ef0ac6b3913c4311bcbfea684d95d GIT binary patch literal 12782 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 CjsAQ9 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..9bbb99686b37f7b1ce5dfbfbc6301cdec3712e69 GIT binary patch literal 8642 zcmd^^+ip`w6o$vQyh3hFRT>F3pthG)1tFjwq5w)MRk+)U9dP196x(s*3!a5n%Ow|i zfl596-&!7K_V#vKP&SpQ5Y9f#o>}W(|2oW?zy7=%ZijYw97g&*(C~^>tZiLUmt?*U&JlxllTjA@))vHj1v3 zp{_cbcc!bp{ub|MFZ6^}dN%r0V|mAl6OC(!sh)SkODQW^toNPb=M2WdLKt4 z-&kK3dehg_p6L|VVD`S=O*QHuywdw5`A{>?!aZrz4&Uj2y;fl1^QLt`>q0ZOHS?Qr zWYV03y;je#EcDj(Ki1n5ll!&aO~R$V;GW;T)@3MKJR9hKtS3{uUuzBZ46L7OOxI?g z*a~Cm#)>DB2Mh{n#FJd3b4kT2L%q$BLE>V8%$qRRd!9@+(pLsSBm|9bW#JpLb5o2t zkR-#fZqn?VW>e|ZG5MT-Gg-*V6z2F;cI@5Ju zU%~X8H;nISp0O~5F9Xf+(#DK5C-Y(1kz@iBq{aRnz3Z7}vCWR*$Gi!BXRq^=c{VkJ z+lo1u3)#@+&?Lj#PQ#bFUuLPZIO#YsL>R~T$nJ^0L{sEQjBoYSEhTnU(i#e&oZFuIq)Z z@6qnUxPhb>3km(poEgaj$3o->c`8VuQNpzBeMCE0SICd?!Ldey)v?*AY7KOVzSmvM zek3#;KQI6##{v#tYV;%!9ehmmU@YF0$9jC{*JJg8kT^BAk~!SVoSBaDOc)_0D8OwZ z7Muq+aOvrrLe}Z)ZO+u>Ln)g$yRhAnW*}OvwT>3Zf;8(8H-@rdTyL(?9}f-BA9cEI zh^aAOkrhFMNO9ko{%^8cHFL(i=4<9T>nEF=NakKZewhpDYHmo#ZfNX4s5zr=g>Ni> zC%%Jxo^giK#k0y>@qxH_Dcj~5r5rUpFEyD-U}O~`GDphfRY{3rcqcY!mLVfW_qfh- zT|u;pmS{?jO|607%=EYFhe^8V)61TDGsDr@wd`;1k!8=TM#so`=4&QGy`QGbm1bTc z^+T@rW8-&KKiJb=S??8k=M_b&6x|n^M1bf@ti>a#I!5yR6sNt;W(?X>FZA@6TA$jU zT02!xPtawG8=#jBwd8B7j zHpR++wh0w3*$~aDku2IKX4c$B*I|ot3@0*rwZdMD%85$*(?`7$ zmL>Z31^isD*1XmumN6UM493OXhj&e=IlW((=jP{28PzS5@~Zc#u$k9;Z!M3qYb96E zz4C5VedXsXqAk9TRP|LOSkMdcOjzF6c~^}$%)!2zOkVCekiByK@~j^5rFRs2Dqbhi z*P~XT9}~Np53wG3E!t3dsZb=uqk#s{+rS!t`Zee}GkFjz){F2pv^>VE8;pXI{ z?{}cM5q*YE8C7i_pT>$y{7W)FQ9fO3?X{+h+T3|u-nDqgpkAZP@I||<(=*w~yUg_N z@MveRdl^h1`cZcu%8K-nlP`OAqdNh&@L>AgjG=mqTzhCwQg1wJoNHRub6el|?z^mM zU8L>)2Rc2ft*NfkXjdA=s^~*>TJ7JQT+kJ*^YiaR?&*HljIaMF+ox&=_W9Yzu6cht zmq=XBzkp-xs`&1zuKma6ZZ0F;(B-{kmAUyB*K22D1s+&u=k1c6{VuojYW9#tSFvZO zG^^j`vtD1OcoMd=DEGkfWKSLCvc0cwJy=;ji_7hnXDi>=dnHI5B(tyTel#WR&(3*V?{dSh!NHI zGpkO6QWrX};&$GhNz|WS6Jy|7{h5$gW1M`{`35I1P4UW6SvN$yQl%Co9>z26oMF#} YT4ATIQDS`8PrD-1E`%>#xzsoQ8{|d4t^fc4 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..211e71856a105693466710795d9a343301e8b284 GIT binary patch literal 7018 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 SUR3{GME{;*e)s)X@A_XEd&4XM literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..42395b25df0c555d4e8c466eb50d2b4ff67b2ba9 GIT binary patch literal 10347 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 CCX=%O literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..58af832732f8674ab93f150bf6b93a81cefc46a6 GIT binary patch literal 12635 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..bcf691da5d74c63cc4a3b0185618f5535fdf8fa5 GIT binary patch literal 8818 zcmdU!TW=dh7>4JT{)$aS2~;!{aETBNw9qO&sUaXP9oub9Tqp7&AwL*?L$84Mnb*^q zS+8kQaMa35yx!gU<~zLKasK}6cDNau@Hiane_#J!=`#$IFxT&sFx8#YFbV_R8|cnq zIM;ukztG)@u7-MNNB3@q+u>Tc9&Us$!pGr`?%W7pF0WpOUYNzzyg$*^Ky=S^HP(0U z4fUSxu*)dEJ=MEBW5>DPYr;bJhha-szv%Zut9ko8UN`zR3P*aL-iE)KR`&E{th=Kq zQ`!USV?A5wt$ui^=b7_~D4vCHB~25)(ODQn2HupN-h_X$FHULYtsIv?AVtqldv7-JB&Omgp7gi z!VwlYTWY~N-d^;kLqf2B2fe;_(D>6IN` zi2|BIOXwKxxIT&6hFdf~(6f{){Q32Rgf=aH6#%;Q`r3T7zxi9nSE9 zY4}{fSFvMkWf|vDBfQ7^33GF;L{j+giT*^qbz$r%u0YnKC8CioX&kC>H3@%+9+Db+ zN8xqk%p6Ze!=4Hru?0H)Q!5YkgmvH+^bVqie$dnNXyc5qgkCg`ZtS~HwHkb~gQJDD z(nhN}n?}pSi!n`1c`aKYomZfPO<~w^i2sf$eQ9Ey$Of~La2(9E9GzM0-MCGnDNX#{YZ-lR6hS|}*ed#xOzHyo(v%O`r(GrZc zWyiNl|K^>{)qKOaKbGea@9tDQr0m>VK6Q@Xln3sL1N&7Q@5F<|U-HgXAKNN;zb8si zbFOH6XQpMpTZf_dLsBA8UE9=kz`M)6T6@%#(GGX;r_JdCOR*D~f+%>boSI{=YdqdT z4`juWzNs_ei#ji7JFqbkQlLW~N_iQde;OkxwI%U%HM^4WT%}N>W>4JH4%8;B$~pFx z_85ptsxG?sHM(5M)LGfw^BmsxM2#vM4LIVX2e=_llu^vG9Y#6H<>NQ zKQvvUz1%alby>!xtHfr_l|A}H(=3>9J?$9Z$_w z-3QW9;VpM1A2g}pi1h6ai~JAAr>gtWh4~t*BB=WS^e~B?tS2J$(#BNgtely!dtK=y z?IC08++C+I--0R~Lz-xPS74Fr&7kG`C`Dg;kBj}l&_uRK6~tBS-h_i9ch-Jb^5U6G zo=O<6o8yoS-H#c_)^^=gR}9#iPv&}GSsX-CB@Go{TuF8F&Rd@}wFE!KTm~AM3K^I5 zvi2LMlAbIv=U|$7raK8=Mj>54c)}-{Z}JZQknnXk-pRAjbFdzi345!`(r3Q*uOU8!w+PWTs=_jd!GGF)+!@= zMrXakDD9s8UNtIf&Mtzg`e{W`@iZH+wTrvwi)mT)nU8Ko{tk03S1bQqKvsbne20)lci#fkrvAASSiD zDbL0{0mf!bJ&Bv1@ur9a9_#5tZM)3>Uc@a{^gPAgc*ZzZHa2Q}K3Z~~Xf|`XCK57xFF(sg=4MHgs3djQ{JUlww`Wl#dCe?JV7*1`NY*p z(#?M4A)PJdih`3Oc26@1pEG!ZoN4*20DYBlZ>DpaCj6?^^!==aJES<%|MSTE+i5g$ zZ!&P!So_2wS8TjZj##v^VVaU=$!5z8d9nNm-?b(UcoA>v|abbH@*!=X&oS_&U9{ literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..19970aa4451468ad6443b9d150153e046d622f9d GIT binary patch literal 7109 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%0D|O3>O?jL_*Mi7Z>$FHbakSnC1xO^9pw~IWIf>T zA<=C_vLA^;jY6CXCYL}_^a@yT@c8j!9U_HI1J*c4x`Fj<5}PhvK$3y-R$x2y)XBfI z#ov^56n{fqiF761z=0Ftp?5SIn9=}k-BDZdN{BzfR#1k3a3@m{G4OQ*uaIV=XUQ!M za_p7;Clfe-mz=9f%dlzCm{ETWvbd{D7IBhG`jEb;j^u$YW-!L?W_qrP_w*B z3C(jHo5{FQP0IyW)dk34G4UotAn~3BiT7;aA8}xs&59g}+?y1EnHJ<`LhhYxDG^%+ zbH)rIqeIsW>64k+Et#B?QZf>%V_?5kq*OliHAyZRO~xe211Se*y_d~xBo8f;mw z&IxxF6$=%ev(1xSQVB41CC!bJDu}3cWC97}*GM&qfR<{}Q4$qXjR^4Qu!Ixl{ym3? zi6+!!0H)aefadqHc|a`;94X`St_~f+Y9UlDl-5qDtsWm20uVLt%aR>%pNm84DADJwn-F%2b{>h`J9iD#Znd}S4!j(Q?iUg9wU$c?`0H-%vQ1tmM?_mpJ0!J z;37FIstP3wjetzaD(Vgxy8_1gVC*swC1EAGcHI3Kj5CwfV#SrLA#1^J){`jNKsJ(1 zRLBNcLTL3Us^jrE)>)lA4<3j^^g5wYYk;7lvoQ|uYGf-OHtwt#nzCC^EU^;ZFi zRY-*lNPji#X;}*|kZr(eWR{mm5@I67f?5>RwHwHGvIDjK4dp$ zCcBzx`faezyW~BxTf}Io#1@lOxE8FnimhR*A)&4cRlpVNF2D((P~CVS`7p6zayMLt z>-Q%TJ+hB{ME0*BAF_2T$j59w+W<3wl8Wk*V$66zh@ey@l_E=lwO14W;KbDSV2$+N%?SAy)D*t2Xo>>#PQyU?VBD5mwWL$j7^_2ZU2@l#m$ zGx9mv4ZL$Ddk$9K!nTT9aV519s{*AAZIa1BpuVOpsf4e|H&-j++I^|C?+=apc7%Oj zNbZ|l=U4Lk|FzBzX`O!>*QtSZwl`acDyjPFb(-lGZ0PXtC41=t!2=IjWLelH+o zJAftu+$I%p;|=L`7tKK}*z53$>nc_(-^lK?`$~~{$l~;r#DO=cc1k!>)S`bJJ0ufOhsFBcOahJBp`u{mL z`fpx{k^h%+{+ril35jP(64TlAZaRnFL+8?a={$NLolozl3+MxMA$^cOL?5P$=p*z| z`WRhIAE!&`6LcwEMxUfl(WmJ%bU9r?SJDQ$ims+>=vumtuBRK=+w2|oE_;vdW_#HC zY%lwO?PDLZkJ!g-KRdt@+*W&azL~Irb_07yFET&c0w@ zvai^A_BFe}zF}{0FL2wq?c5ITMeZf;W$qR3Rqi!zC-*w{2DgiQlY5JMn|p_QmwS)f z&Ard<O(fPTFccSp7HNY_ZzXmSU z0-T~VyyU!%2;@e1_g+e>NG-f$e~dgw-hp@Ke^5+Q;l^_CuG~uP)Cup)J=8}9+JfFp zyGZZM^XX7JnvSQnbSl_rfu#SXpzW>j&U`1l7ypi4qCe1|=+E?5`a8W$|DyjWu!1U- z3bjI`&?)o^qr#-HC|W7f6+IMv6#W#pEAkb0C~6dw6*Cpf70)YPSL{|?Qv9yCtoTdu zw-PCdQlV5UHA=0LSGH5;D7z}VD|;$$RrXenR8CjUQ!Z96S8h}8QhuO3t~{gsMER-m zGvyb`uasXaFDfsokV>uMR1TG(YN=|iYNP6=%2nm73RLB)h-$iOzG{)`QPpDA64g@G zld1;QR@F|`yQ)K~BdTMnbE@;I@6<%CP^;7_YOUITh%YC_p6Vozf}LK{#|`p{g?Wm6d|QWN~@ICDQ!~Prrey;A*EwV|CIWa zMJdZucBJe{IhFEV%AYBJYt$M}W7b$TE{$8`)$p1dG%Yo)HElH6ntqxB%@B=WQ>-b` zjMYrkOw!z~nXh?7^Q302X1nG+%^uBO%|6XXnoF7=G(Tznt@%aso8}MAWvx}4uf0P% zNIO_NMC;cUYfH3s+Ns*P+Q+p|XqRc9(mtczuRW=~q`j=u=&U-QuAQ#EE?w7Am#OQd z%hu)Sy6U>?ZqePQ>#Zx*jna+Ljn$3QRp=(_7U~|-Ez&)zTdZ56TdI3f_q1-gZl!LO zZjEl8Zi8-b%5 zC*z&Qn6chC)5whX8J8JX8aEnu7cM+hhC0cHVZ$uCa6WbbCj8roEHBv%QPGn|*-YZ!fl&*hkpM+o##)z_# z?mp-~>^|x~?mp>0?LO=N)uZvW^R)ML@ML(hJlUQcPghTor^-|7sq;+r)O%)nW_eb6 zR(aNV)_FE~HhDICwt9AYc6r|NyzANRdEaxv^R4Hi=X=kOo_~9O@%-jhdQ-ewuik6) zn!Fvn8Qv^!wl~My)!W@W$Xnu#dnbA8yi>i?y)(Sb`-FF+cboS!?-$;$ykC32@qXvM zllN!uuioFim%V>^|M6iT^(lR7pT?*2>3v3@$(QEy_HaDrK|3UaFftZXfJdSGK4H4TgVZ*3f+aC!mUCtAy?=t z?V2nlxzVWC!-Bitt}6P62`p)d;{A{J=jLqC=OCjS+- F{tt_Ff0O_K literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..c59bf3c4cd1922997e94135ecef05480b40ae339 GIT binary patch literal 12699 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 HU+w)b3Ma!1 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..e856f9da5f1061b130534d8ea5608dc76ab44b30 GIT binary patch literal 10258 zcmb7J349aP*1t>kG|6Ob+9We!6N@Zu*%6hsSSh8DmK{oHhZ0Gfnxs&`$^`^bb_8S* zgtCZ;fCvbP2#AP?AgdsVxGT85MW5T#@61e6%JRMMec?AWx$C*-{O|uPGpaHiip4WC z&mxQnqDY0*NJBrM7X~#RCq`qTNX4MWkx>teCGptc#=&UGm=H7Is1a(6nxU2`8}&kcQ4odD!)PL!gr=d#(GzF^T8N%TOVJ9n8m&R=&<&gU9=U=rmbmPnolRv4fJ`sk-k7T(HH4v`V!qjx6*C&WxAcdLU+)e zbQgV3;eKJwOlAL-b90n7&1i(6{MP`VKut-=)Xtd-Mc7Mb8#B zuBZx!FCjfLAR|gaCS*ny#33uPAvY*Y8#G5PK$Mn=o3@&1lm%O%Oi*2)s(2928xZ4bQ7e>% zGK%s8@I#r|8s%)|Y^V)ti`t>~r~~SVI-z?}XLKLBA3cD&psuJJ>W+G#o=nGltSM{B z`m%v+AzQ?rVawPGR?9ZAm)Ohf6}FS@X4PlWgD4k01Tr~L9_oYgLDE2^Dq13fm3oM= zc&H*M*>qrjATKyd41?PA%)`7FQ32|Q`op{cDnvzS02+t}p}}Yf8j6O&zY(YyjRbIX z7sFwgn-c{M6>~h8E*u6c=0(avCBblBa6+Ui-Xj!MfFnaCU#yPz7h{!?ic&EOW(ZVO ziqUZ)aXd&iE+-r;0|+$94-~?%oRAnU?HUf1Rg{YrFsUS-TM-lEu>lH|4bBhrtdLY$ z%2Jq7$I_XB8LZgAVf{G}dlV`G@rzI?647W>hQ@$N0#&1=tzxjREOH<;QDlgXV6)jo zD@FjmNt3cN+co#M&djc9?w{1AZFX~ic88jp3ur6~!*b=Q0!2_IdIUv5pK(-$#-Z`3 z8cmP@1-g(Apxl;tG!h;Fn}L{c#>z-EUd&nZ1KolpW6PqEs*2L?k#I!PfOJ&(I|vAn zj>B1{D^|B$woQc)0=uL!GqW-mGuZ$LsNgJm6xE=|K&r`zp($u8*h4xHC~~wc2mF@s z-Kfi5FdshF6fd(d4$ROpuc{)X&`v;@tDDFerZ;$ol7mhFGnNc#o#BSnv7T7it^#k^6W0=y>QE&9fn&@uEb zI*#50z@J3#qf=-XI)l!_-}C5$V$PNyC=jEeNNK1f7f>7>7YxHq=vEbvM=BB*+b$6V zbOGszl8z*(%i0IZ?)gYn2&O<2Sg+o=-11-rQXunT$=qa_&g3U zm%q%I+66HaYh=?w3u_1(YQP$^hTKsOj{p_{q=x+pHS`$>)9JF>fyGPO*XurQ$ z4i4JiNA%}`?V|lWL&MVF+fINfR>>!5#qyc=GS*@p)?)+ehmFXFQ)Finz$R=)LokP} z*oH=82dc&{oC;6c;9fwDl@f&jo{D0k#Fjac==fl?G!G)%p#@QKv=|jDAe;bfNxlS- zBi*qfisLDQAY!mg?a~@>@p?pqWrY(e#Te_ZV?9_m)>Y5?!09q!YnI8f&dZ*n5S$(O z3hcpNcz9HXQ&|-o56=WPQTEKZ0cx?8v*3of5pIl|;Ja{Bd^gU(&G0?AIc|Yl;#N45 zWwX|-4QtEVvG%M3>&QB>ds%08AG@DDz`8Kakjko2;ZRA-s%W^Fa{||f0PY}XtYB0G zPAJJKIZ<&?p}#OUC&xdoP0LJwWe|u{?)S�qI>UE5oAy!NNXyw|6#^XZH`4jPXm1 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 Qv`Mu4Xai|dk`yRdx!{T$ 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..f927ba69efc97a1452aa381ee90dd5e8ec3cf8f1 GIT binary patch literal 12872 zcmbt430#xq|IhQhFJp&e?}o4egKdm$FCGL4h&PughKPcSq~L&o)3MPuP&Dc>&0m?R znUz+S;Za$6blPRvVPmP;%^hr<n}t z9!5{0z36px7#%_HqW94U=o9oc`W|a>EVf|>F2@t`WIP2=!xv#64&(Xw65NHC;1&29 zyar!~Z@}wuH@*|^!1v?b_z@J1AIDGOy?7sf9v{GO;kWS-d>ns_Kf#~kFYtHxd;A;z z9o>!Y!G91$Fj0_b(vPH*0VIQDlU$NV3P>55K&F!#GK08D1DQ+a5g%zM9i)p~N|unN zWCgi~+(d3B8_DgYn`|L>k$cE)vX?wfo*~bY=g2m6LN}tNxmgNlHbVhoRU*l;8t+ga4Wf0+)nO(?g8!* zZV&e)_Z0UW_dNG0pU9W<6Zr~$5?{$r=BMygd^JCnpTqHNI-gIK(VMlibL_ph)gH}CBnZMC8LyS6;)FLf$*$~s^Wm( z526NA7n)g7HObo)n&$SkdqVYs4jyGOlzU)u&+~?(Dl( zsHmFeg#n*uy4T+nm=Dv9e>45>H|hZ?5DZOAYxKE8p;{R*Hk%R}O%KyU^o7MZiblcL zV$3hb3i|pXWCeU}DD@&himj?}w|Xc?`Fg=rHFauRlRNCG^aNYI0C2!x84R?xg%2SI zav~QJYvqIdu%t$AdO~%uPkSgFXqB<` zLd8@`lc|%=qV@C!x}M%dZ=qZ0ee^-Pn?6OKrq9u$!>AOEL*oIK{%8Wa5S0UjRe|n5Wqs0vl1sc0ISj%v^hR11GI znV5r=6nlI=SX&wd%G3)fz(b!8*jXNE@iw}B@Dxv|E#PnR z1c4V-?QNc5hu1S7AnPdgxm!RM92Hg7Fs;<<@ii6tyeb>m37cp?s!`HJs-|i^Rts4527o;qxdHqt)PNdM6Y`*DU`17X13M}N=Sm<~c^7&p zqRn&_U9HEcUWi|`C@V8(kTpN6Ymjx(kUVJSWOsGFjl5_s>^2YiP%HAI0BQqr22luw zQ9J5D^O;ZqDJ1x1tqBJMzG-k4KnWGKB>5{ysUQYVYCn}LYDxT zUFcGD8KS@+h9D5OSpp26nb6w{oUkE$^!?0KM+Mj^qrAP*+vFY>bOTqWmdRqe1TBRX zr2tYlT7uHwfQ^@-|DY?;RcJZ78m&Orpp^`7h6mf10nOS~ZEi`tirrziFVMn@A#EXirF05V2wMw`$U zv=yZTj)jsnWW7D|FT-;ux~qqolGtuRccN{~tD$s|0LE7)56tX&n6UI}K)ukv$rEY} zdfS*9_8uzlxdZKlap0P_VN!e8=K(p9tZ^W?3GG0;P&(Kk80+ortL+b<2T?hwa|(4( z^V{dB^Hj7OJp#)7n54{mP#v{Wi;||v8q`k(r!HEQpE<~yo5}Pbd*~o*c3xN4ar87O z!ZYYu^c<+bTu=n268q5eXg?^#3+Mp+9Yhbn_bcdC^cp%;FBmGSz^Zx!P2R>bknLcH z+Xwnl)E*88{5{$p%d7?rfhF=VLNNu9SO5ln?8WU~SOQ&APh_hSkI&r+$oJVNTS$og z3qHFK79eV)HiHs@W~V^YPE&>b!WETg^y3ZmCesgl!GIn`;QKR0kcoa29Rn`QJIlO3 zijJdq{*Cu1(0ia{@{%p+M1=8mt%0DY%-G6=j*HHu=C^>1pMrau4OXiP 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 AumAu6 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Info.plist b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Info.plist new file mode 100644 index 00000000..692e02e4 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Info.plist @@ -0,0 +1,50 @@ + + + + + BuildMachineOSBuild + 13A603 + CFBundleDevelopmentRegion + English + CFBundleExecutable + finish_installation + CFBundleIconFile + Sparkle + CFBundleIdentifier + org.andymatuschak.sparkle.finish-installation + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 5A3005 + DTPlatformVersion + GM + DTSDKBuild + 13A595 + DTSDKName + macosx10.9 + DTXcode + 0502 + DTXcodeBuild + 5A3005 + LSBackgroundOnly + 1 + LSMinimumSystemVersion + 10.4 + LSUIElement + 1 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/MacOS/finish_installation b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/MacOS/finish_installation new file mode 100755 index 0000000000000000000000000000000000000000..5e032fa18e4ce6ed71c24f6bfd7a119b64844f41 GIT binary patch literal 138260 zcmeFadwi6|^*{auqXvy8T2xfjXoCWB7ZD;Vw+)~PAP_~ltRdMzBscfMMWF?kWLY0J zp@Lu)0WVdwRH;`~q^Jm9s9I|)A4Q9m_OqB&Q}tu1Qu)2#XXbf!cC!ILzuzCf-|zKh zUzwdVGiT16IdkUBnc3%=y!pcmTP@4#fN(s*F_x8!=<`YV%FaOEBIW_GGP-nP9>USj zQ3)KCz)=YtmB3L69F@RP2^^KcQ3)KCz)=YtmB3L69F@TT&m{2ncmMc7Z~WyD;0*A; z54-$&?D)CuAB5objvqG4bE9X%IHPksCTQowdhg=P>z(A8%##G?!#eAA0x{b?7U4LZ z<@E-A^MX2oD7F5|ZkBcb49i;CSshron3>ih2ljdc^Q&jnR(S)#5K!CD7-(D8Ebun) zHgwRbgg8snATOYS%HCPNsyd%P4UP57EbDEYn5YQ?k6lO56E|~lY<+lT2k!whHBqEs5|pT}4sfBmDDm66(kExFtP6fnX?~FhoDV;2jtQQi8h3(NGy;ht!dcEU@Up>Mgwhb^Dz_>7W^y*|J z`2qh`rAF)N>Te=()HmBk4ynq=>#g<$0;My3Ucavb9Z99J>1E4`qw*$vO`%cT+2tjOr?r=2JM0NBcwJ&vVTGm6LT?gGTWr{4L zFV(f>p(}s>twLk?q|(>}8l8~8=dd)&z(=A#sWe(a<8IJsJrWJy%v%3^a?zHL zrN39}{L+^W*O$s_&KA9lwCT$>(4Z~fb{HC*lFFYb8Z-79&&V+}-2A)?8{Px)HWhQe z6W94rSFq$;%ePt9pAokJf7Y3nbt2&L2>i^{AqVjsgqslB`)q#OvSKK_8~V7!K%#x= zf{=~SClv7asj8gOM=xP#Bab|6FS+8a>&FjT@l3@T=S(cWa&12HM0qn$u&j#Q#re*ca=reJCAn2>^Q&c&_U+SOVr_f(o?VDTcpB?B^ zSR1OrB2ige)4RgS?Q@;aA3#o^&j_O&G)aGQ68(RIelP1V^oP~eT~irMPg|8~x*XmF z-_-Ps!_ggqnNpgL?65vkB)m>dqWQ$`BhZ}aD+~E6gY(mqbxJkA0}R?38NY!Xz^|hR z&;=#(-otxCCn{$s*_m}L>l7$Ka-ErFW!^yVeohtXL!Hr%W%WhsuyTP+t14jyFnkkz z{yCLpzCil!q(PMS%9Gl={7CJMsP+2}-;jv`YSbaF8tz!1cs*A2RfivIzwhvR%0V}A zbUVrN-iO>|dDqUkxvcjvSKQWxz>s;k4fX?Ycb%p!Ir=#&fuj;QDuJUCI4Xgo5;!V> zqY^kOfuj=me_sMOThYIT_qB#wa_woE(JuM1;;d*l6CA`Sa+@(UUTP8vQzaxfPp|89H!(?k3b^r4EPQy`M+SP9okP`@Wc` zB|0)cb7y9LEl9_wft5ogEiq54&RxUYQOLDDt)P(=&CHKyqu%}5poDWYe9(vNXfQu3 zx*$Ij%oAe+jy)KEQHq_)@>$%q9O}v=%;kr=W+HMr+cQoAUe@x&?MTroRP(ghkprs% zfUTG(PBNFF!RU^D+v>l~S%Nc6%P#I>mvpwLb+SFV(ZbB=^sMN0+0n7NcGE#tgnVsJ zJ}VwT`_aNqcX;xa7Iup-K`MM8Bh<-`@SKSaLcRP0Z|) zoVgE~J4f+s2xa-nWv@$FKFgvDTkVFDy8w8;u^Y~D2c(r;J`B9@_T1@Sw@Z0?Btuzt zVHdk;I7d>+Egk@}9Xb7%_-?uq`S$9uEKMifPD4%Uk`1JlbbFCXQ-6c**~p0&=7oQj zYX!6H$OIHMA7@9dBZ?l{177l(XYi>+@3qNicC5J7Ve)hkyJEwC4jl@eYDXH`ZB61C zA>nj2+|qfc=U@ji<~e|G%%1~FH!?Gjihm^7okc8aI%~O1%UX0>H!Ek!-M|Xp29D3R zM`YU9WJxpG`SH%ESidcFtR3jwJjRZ603M`BKC~2j0ReL(`iTu~?~)(?$8=&8Do(R$ zN1|U7*9Hzo=m!)>ci55RgwWLnp?y+uEOR(%HTk!ZD|}7a>1k!h?B`Bk)yT<0V1hy5 zK_PG*a$+T|7{+Y$LD9ivYCz$VZK2a(F4(nLbsYeTwzm5|yso$S>&swT2P zF)`gB(g8q#c_L5owXjdAwj;8c1MX?HBO3tNP4N{->RufHKBVBuvM1B{#y2BvH?f@q498HggO?)-yMh6)nuSn{o~8YQgSg zu;&zk-PFY({sRsd z?WR2B#8%%O2HK?j+}LwV2?f#fuVbs{sa#hBc1ewV($M2+hgu;T%)m|*KH^**^N`Gn z-^&VVnhvLFnrlRC^@fxtZxGCGY;r1WZ9IqC+7SOEdTU0NOTqh}d8WLzn z3BI1fBAGe4RD!3FZmR@(-t17w_VmtnVZJO%+eNm0$)q0m2ZX=?=3otgJUfB?TpMc@ zl!|m5`H2R(7Hl@E84E$UB};6>WP8yCzYtQ+>N#8xv&4vCwaC}2g(qv#ylz%-gzdo+ zFpgC;Kc|vsj8d#&-6DZ<$w;j6FH9BXXT=)dQ4r@<{M;L5K8d*+3)q=YLtG0U8~goc z7Ki_xkrR1UlyV-XjNP<(d7{z#P}Od#GIDI>L_PcL$O1ubF^cL0xiygkq3~BcD}EhI zBD18%u0(nKN~!UUk<(Mi?@dSk6d|&x4Uhl6fgJ7Gl!1Z7B7C63g7J1qwtaPGw78|; zx8VcFESO|pofR!^Wg>II)i4#qvniv#toUkF@{e6Gz%I_VZ^;cGIBr3AdsrtT z^O^m=)%J3yrv?47`hC=VY!vh6YdA4r-Y(vY5$IwU$8)y60jRU9Ewc1v+r=#$A&eIW ze-9~pKp9?y(eX=|lSZg#3#Mf#LPx>ObhT+834SvfTx|<)AL4i*vMwplYkJI+%~{j1 z3U%zpHyab<`x2_zjTgZEvz3*%OK5job8(-PpNw*JKorYHPIRZ;a2E4u`x`#|86dE5 zi{PGX;Chi0YvcnkPVGNk57-m0-Z_|)ovJQRHX_ z$0D7{HPoo-d#F*Qvqp+Vy6OB<5TJ89-l>i$TZ}xrX_Cru-O0;@>uhIi+w^cO$4mF{ zM8R#_L-c{ZcGHc(jjg`!R@5-;*q_i(%z?RfM9P~gSguVny@h8~`So_B0mExI?T98? z{H2l+iCR09`^L)Ov zi-F0rBaacI>B)Hp*J$j}1iIltkG<|VaviB5*HCBB<-qJkvEB5h%FK;L{>lbuNh9wm zNDTnG|12=unOJ0y7oa8ti|tf*-MHvKa??&EFNZ0RX-A$~$`0j_nllXO zP;cS*FDzSqo@yy+-*GbeglP<2br>T1uVuGM#26STZZ;J+{uWB9m1jT)?WU`Ur8Vof zQtvb77@q#Uk{dSgqR7DlR{sFV*^%q#Sk_lLxd^9Z<_lL}a`53Ht(%BS@sGzNHI-w+ zb^7CJ@%R|jM~%owAFtRJequKTKxXicoRLkn0PKFvXARyF%!)nN2SR8*8MC!$ z{Pjo`$co^L25t{_{fsrIUf5|gtjbJb}9 zYT1qVqBK_W4Yyye&JAI|`9`u8zaB`50}43%o%9$qoJ``4pVx~d#J{>&2!4T_6j$t2 zA<{_+8z&S(!d(Q)q(ZJ~^FAHRR@Etm*=B#D7W2SMd!%A4o&vVrSYvQX7{qh0P=E!YteF z??-Fj*@I>AwFe?)pUFL|j2R9ju;(IcyGX8(C!JZGxyI9I~Q2`hEm`Kb5oR55dW{ zJmc&M0vc>bc5#54HgX%TM7#8l@%M|Ew^^SIfK0aDJ^_e_LU ztbI+Ey}HvaAo{i4A6?1CNd;1N0pyhJC==Jx7?HWMWl4wO7E^)?k(*wEaIOyBjw%at zMdDn)lxvlTDm;x=}!WB zsIB&Nv>jWqmU?M;D;ELHwtGm~<0xys$PQmE_@69BNlB|6YOxo_AqjPK4ULbjXiOpU z*Q+U;o{m!`GYO{{Azi!aCnW2v|5D*1$^gH`7<2V*)_FBL4ZmGn1?kyMhkl-@bsK9%nwg{JP)T%! z8M#yUUCIK#c3{5zl-TH`NQ0Eo$sD%T z^lKp7CHqW;`F1oN!JPWfGRTZsWe-Z6DtpZ;uj(p%RNIb-;B+gGx>aJU1Dx-MX2zse zs5H68T%$%frN$IhqYu0mk$4|=mBPjGi5C1IpwOXu-U2Jo>}m04=!V&g)1`r(tg7o| zA_qJ9h~$aX_EBp880B==9dyX;1LQ8*h896Or~Vx_6S;)rEXOnED)<}048ong%ow@V zq?$CA^~j07TK`eBHK)D+-cj={cGH6fdp;?*BYiX#y|RoYp(Mm1lEWc28NLv?OSUOl zgf84a7S0p)p8D{q`84#TIai-ZMMEvknNX?>8;1m*7RYhsEB3MFpP;kWryc$%MQ;FV*I(HePUOD7_{8e1zesH-MMJt*ZB2hJqIW}7E@~f zy#lVf85x7@r>;hp9Ujhay8_hh6?d|Pjvfr)3)P@y=<25);@!-{4jgK8m9oS45I-Sm zSgjWYtA^A{x}bVzAmbNDo>OC8XG%N?ENIX#$L(vr+75RRHvYT-(5HGloP2xgd^?>z_y#f~i8^+}KIGbsd(FdxA^GunD1-G~vX#o( z5O;CZI469gA^H0o1x1l*Ng>lu$OLb**S3;G!*X=VZu|ytY}KsUUC3hm~n|3-IkxgOW3+O6HK{%u$j#G&!?Bo8!;%xza0~PL9@`(&dEO zo&kiE{gL)b?eMeYpQn=*x{h|CKOV~b78`xEFEn_4jrltz`zto5r_lmL2VCT1Eof>bQrM=b za`$}j4CW@)I#%$u7}USMDi!Bb<}_^sPHgp{S!l(uaIdj!#Av%|dx8W9K7&kbKw;{x z!kGy#7SRI?_vN>}5+^v0=mMl@-;JEuid>(xmK$4PDF~}m9pz_mFar2o`LIvI*kl=l z&|N6)C2h`%pjv?V^F@v@=1z&^bJ8L^dZR(*vn$yNbdX$GpCQN|0p=kj%-xeavl)#?B;ZA zM0vO+^Xr`4;=NzzOm2F;RES_P8-mTZA|&#Nd0q$p*Ey#YuZ-W2sI(F_J?}T4nRETN zobI08NC^p*d>xS;*#s)62Q9$2b4-d39 zz-)7lYHKr^mJBrFSqV9y3ni&kHjv7_2`b=zs%Mi?qep6uyIG?$QDaT>DXP5yTP3m*^dCUrTvc)*1DrE{dPZ|a%r zbV~L5H@?d87U$xTGoX*_Yd74*Ljg4>9pBYi-@eLu<#n7t|Lm>sXBqKl3edGtqwU6D zvVzg)HBP~OELe~bM%XF1mIX>et_7_?Vd^YbE5j5lOm^WA9QF)8fSGKcQ0LZ;_a({j z)y&am!Dx!qV?il5(V4E>&Je zL2UJXlmND&=(8-}*aJ_64_;5C?TG7TG#oQd;N4uiYSM@7)MOXWC6aBOAr7_^Fp2UVRVx zWk0urg#$?el+=$xc)YV#Dy~)X;vOX1j=W7wwr93bD2NY`lzHgD(+1dj_ctVW=(0I< z`}v!c9a*K=&y0RTB{?`i38`s@lBsS*ba^kz9JW8?aICx13+$=+1Jn+wZ)}}BKsq(Q zr#-C;^1H>>ovSeN(Y3tTx=$#asn~YHZp9*edK3_>S1TEfMZQoOuwUx2K0ec#O;y9B zg{s|z_7^S8vx2AFO%-j}Ywl(@HHt`YMw$Jb#^729>dNm`1mkCbPkyg>_cj_(U?(bO%aup4)~(H6;e* z_xmo zy|;#Bgg-gN-Eq1fNwCQ%MN4*LvD)y<1XT-Nq6{K*<>E{hwK2v`tI$3i3wdr+}O# zUx5CLY^1r1-B5|DN$0|R(0c##D8&z*B&)YTYI}s?RX_0trRmn>rq%q7PnNRy;GLmk z!-qPA?zJ1biga!;SRVi!yKx#DU)W;$S!YXu*~^ZSQ)+ZkJzEfO?Mo(o$sM4(^8pG* zTt00telyBxxD2{Ccv-LEyQv>oX5wDW*)En?5z<@ovnc;de7(=zfAsJoXK=!JgJYb~LnCM!idZ z^9ceB$VXQEAAMMLHx;TIMzr4>(c*nPMsH{_HkBCt=sWROh$_G8s6zU-R7r* zLO6{n=O8&_uJ*}GrKTz}RE0vSM$zC`bLy``PI{v4g19 zAEm>xA&R0wIU=ZQH;yrKLdc0W zu!6g=Bp#RW+RuH5b09migEeGeg@vIc(^SJFB1aBjzlY?04%FD{9@n7^o?~qFSqf4X z4J>4`LCl-}kfz;qwZY2gJ(=?ba}1yOeaUS!@LoYq*nPW4mOQ2p%bIi_QlpVgRSP%0fxUjHIx-w`#sag#nzsPakd-SF_HpA!osh1pS1WR34Hr{Wr0ZuZ$XNy5uD>p|(sZ2@3A(jG z%FW)})An&ImYp8!sbVP~kU8RLl&n`HqcB2Sw)og0Kaw9q0S8mIBb{ixM0cFJ+rcglN$F|N! zoHO!3{0UIi;^dl=r&yA%JgzWrnYC78hWL`w@B@@Vttoly;jPT#467O#s{Gw z(epo~?|D4lO?CO7=yGi9Ti^rl5`+(&Y8USgor4~S50nRcg%5NL_6={tiw+rcd&jo^ z8d%L2h7TMcIzQHM8xpatHooiM$nhL#J~_7aMV22I+j=izN9*?3Yg4sOy&K@n*!WU# zVu(p3)C>wr>poJDGizL}n;^B)ibr0F=r84I#B(MJ)bll2v90HfMmzFoT`m>DnQw?Q znU245k&;peu5#)nx%tTAZ}mA#{s9b4iJF^+PW*OV{{^7h4KropeZYxF7eL#*r6h=z zaTImSbsOI27+0(6BX`=3qLjsZ?8X%Pga^N44JTfYsxnExcf{pxo|HEI6qM51C;bM= zF;bpJT%TVE(wMAuh#j#x)~bloOJl8;0heZKtMpn;rz7jZBDMrMB+OHaqIiLz6@`{r zdVaCn^RpGyMp3#;t@ahAqm-xVd23gW*=;grQ;d~vH}e}gTCr7^vr!sRJ(gQg#`WuL z;zNljxedsp2dQ+xk%laBG|COjvsOC~>HVs?!fM>Vi zi6Si#hAvBHXs9rBcy8`>xv|^f=DVL#2<>q5u@ssTA~!pcn|L;Fc2!w*{7UeGhu3oI z-#pS3NO}%pAt)uLz(?i$F|3Ct{#DNOhEe00ke@TOu8kLFlJ($4w|~EO`bX?8`4}fx z56+N^X}YLw!M`p@)dTkOQ{*OkSzTS~k52|6>E#h8dQvY}gHocG^g~h}2bm)bB=_ti zw`Xs)-?J;EV*5QiN6J&j?|AaF+c*&t?^SI@@!)54G8nY~G!974j!QkP@XqNN^y9qZOo&H1RoC1f6pZSt7^1ag4~LjqqQAZ`H8?P?OV|#mmOKP(1czgpOeBF?3!-(SIh~|5kYofC7yIT!c0C;zEx0fS7Qu{vNiP~ zGxZ0csc{P*bi8Dw{ASGAfhBXxd6tFOBJ73u2|3pj#~Tshe~z%MQ0c8+JNysfpdR0` z6(3&%J`B^Hfi`TLgXM7jB}idY6do*+tz-$8XVoVT3K@vMK`hU{=8_b|&TbQ(Vk^!m z0urCCS#gqr@Du)jk{JNOE<$jgA{cw>A3(6f9}Cat7^8SS5N!KD6p^td8-`qL$d^0{ zB6hedrHltt!%?Dn_8@00f!+3t-2vF)UQB*vKgGx7ZTnKDig0i%&*yam-F)>+dmhFY zw~O#7nM#Vo+I;|_tMqxZDL)zw*@W_-1D(LZ3Z(MXxt1K(<}7)f{Me^adP!U6{Vxfl z^5_>H#_L5P3){9mhDy02gmHBq#_Oe|<_JGN3FK|NSZRrV7;ho*-A1UTy#?!9Qv31e z;y6gQuOKrk&ZOj@(wwI|NPhbqs^wJYAlaCY)9tO-VZ`i)3nodwovrU0)W9pV&L)zo zghj4FatnbP+xqYrRNy1<-$R8BeT$a@2}jfOvHaSNe4EZu)6r7iKxd_ zKOMCdxT%xXdEO;F6m@KS*#vwi|6YANTd*@hJGLSZ6V~Lp0%dq8{>5$ZH~Av#8qu6A z;@Y{xQD&R~762DN$1SkKYow{TA*pjo2R3b`l(bMjD>l)GHRSW%+2o^@wRE>QLi?B- z{zm1>n7t=>2TVL@+!o}rg?uGhym}zU^jCs>kjNO?*ot>k8m*UVd|WHMK-Z-H)=0HQ zDo5!)c$uu*=qtUbgD9PGzf$nWt7hD}(ha#Z48MTXwjM*#y*QOs-KMldXG!f=(!;_N zD?EfqFG_f+bT3&pB=X)_NTa81x!8;nyjh&W#RJI2<61e3e~5#J*qn@<+k-gGu*375 z4x?)eft0K|i(9IWg*gG&)|6QN*LXKnS(&ViOj#K5jpF7rvE$~0FZF|ffvB5`I;$v4 zMF+l}O%Dgl zbo6pFfLl*8A|=^Vb`o4jQOB}ifJP>{j(-d4;ywKdshsCtdI5D~&#Y%_SRQkJx6|n< zidkt^z#oji=u}#dT%*1AuiS9kYfx1~l@*suTcMj`FNr|eH~pX@7>h3e9t_QJJNy-= zsokGK(UxUTXTUo+BOU+*cS8v*VJo1un~5U=!b9KnZ(s`8k_sLRIo*{3(x=+tSCpE` z^HPySg>VOGgKdu`Sz~SUNn<;Z8(Z<$p(ryZ>=@SG8GGvXLa=?vF%EAM*M9FRlsU!$ zOrHZ>WgMnUJC7NYCxdjb+FvInkE0~E!Vj8eTOXf6?w(Y*DP+L&ieCxaA;vDRv15 z+$YmL;V3G*@hpf$>+@*djH1pI?7dRN_g#%5^}5m`De8iv*uv%7;KaKl6NjF2?S>w7 z(WqZtu>VD_-6*YUH5tLm%1Fik2X+T_M%WDvbnY6@B6nD)W2*|dSQ>NZB-Gj=jAC`~ z!ZWQOFnD(3=>>Q`AWU#t)=tkd^wipX?`dRgS#utjFxL=*A(rBSTSoDNKVj23OX`uh zf;EDFaOmTu3>2&-(S}n&-|lR0eT@7yJRn@|0GIZvuLk2=y@9dng%obR=og$PC2RFO zM8kK)cNLh*KA2c|N;G4Cf41dWV;8T-WKvV7;iCZ}#jMy%GdQqfrZaI|Y{j1k>#>Hb z*(S!RZ3;eCnYAAM;uzIWD7 z#W!%l*s_>H%FK_gIt6v&Ydfe%l0tkMKPy%*d_keKC)k;q6LTH5v40)4TFTkk;2tz;i|~wN(#u;5OS5Jxyo5` zJUWR7rZSft3Y`R!3p?d3ISpCOSH~L03dI4SV%Jk|qxFOM{n8M8@2nq+Z@14xf?Q*( zt|j%yNOPOedJ!lNrF)0%y>*Rcnhq=2hT|xRwm^bT->F2a}MA0#L9mGf9XO~b*L3Sa41Osa>LI< z9iPg$0{7Tk{tkUV!m`3wT!r{~K$G`9-G|h%$6DOd!iEuW?Lfl{wH7+2_j0l$s$vu= z`S7m73%IERn&(fPutazZt)UM$X!TTayWt|hcH=dp@V#m-%e5uE>I&c(x>5qJaGe+M z&=Ix$ZTLCyT}x;SMT)vRaHGfUAB<*GjbX5_5Xg$%Cq_q9Um3%V=tZnyMIV$ab9JBC zG!bmHelnPC&!(+Ho%ox$3W$$chA=dz$cpM&U( z^c;lnQe={4IpZYQh>yWptf3Yi#jjrtUftmxPou-h*!#25%Z3wWl-EH9`Yk@!Cj6XL zjd899^&QIa*$X?@AEHeVy@5>-1KB9r6BF%e6zy3h+Ot-)=WKU(u5H3OpqJ1aTa2u- z3GHc5GdPYO51T-dE#A(Vmt+(413Px)#1TNmtkN#fQ>?c`|N5?chiR>cpE=u3Z0kFC zK7$L=iH=DC=E08S^uu>wJMxGJlw59IoLQ;l0T*7n|3ND z)oYWHe-S@1W7Jh@-+>EE7e130i(J~1&FqVY@Z>YQj`h1WCcm=ARu4v5{8PBMOFf@) z)#()dgxW##=Ge&izfXX6JWuV2d_aaU4K_VVtw_T9Be3j9SbA~>d!mrv$P!-J&A>C|pBYEaiKkFt zddtac<3mHiq@K$!v0CF6-$V_s?TsRUd+o5ekWjBTmKrH;&Ww1jh02}ZNfT?u_n{dHS(rtc=TlPT3r6uo< zdM}>Zf)36{*JCjz$RKrkD#j$y=EqqeS3eTvxSE7}YqF31$ZN=t#m3XBaB>B(URnT8Gfjlj{{pJ)xxP zHD8j<*~KYjey+$2N+xq`o94d;p4t2;sTVA?Ba6v4U%H4<4l+1!2h0Z*)l*KtMUAD> zV^~jieDQWlT&!pKC1zMT^^2$*t|V*`EypW}%E|JWft=VgH?c`LNQyOZ4asa%tfh3R ze;W#U$VsicgjjC-9Ln#GOKmxhoLJ0KgKM_z^y02p<3of83~f&R7vKrYb^YI^Yp3)w zf1EiFq&~iHJUW3NXX+W__nF9Du%vUU?8q-6S-a`qSAtEg1l7XKZ;YHNl5+)hPveY{ zoO(4Xx%OQ$DtO2(#hbVQXgK}6-%+z^9KUm z@O^FpZM*5%q4-|ik0iwxc5EzLA14?cfq`7TrVl12)3O=1rTP7QeAO6obuH5=sI5j> zR9jgxXMEiS%L6QW?f=3!JCeDg4XxLXX{$RfRe6O$X-y8O8S?rJXT7QN664xdULqxT z^SC;iBCL^M;PAq_Krjw3ESWm6KHpM7)Ol-OFY%g8`|7?&9rmQ7{SP#w|&@Tdr-zRaCu6iodJt5f!5{tK!uOx3){Y>Sx zBMW&zg;zCT*<($|cLl-pJ>CU6m|VnedV_1NHcC%3ziBc3H?E*6*Hx-jQhFD7wpU+z zA-<{F4pw}glnzGz<#>513Lew7FhQ_BX1^0H#D^d^x}$lR-4s$1QB*NmE)ab73rdd{ zm84V7G;x1|2a*-1u0zEgkwT7tLkt=yrmOXYi+d@q;pmGXVJe6Nx3_456Yd~cBNjq<%ozMq!w&GNlPzPHKu zcKLo?zIVy@yYl_MeD9X;J@UO*zW2#@T)tc6yH&owk?#ZYeNeuw-;(o8`OcE>Z28WW z?@sdFS-!i-cbX_7UPSnI1ur2yN5M-8->l$e zgr_TbIpGNkUP-u6!FLlbQ1BYUy%oHk@C6Efi16tO-az;S1#cw$!@bhqO@zNv@Y96< zuHemtKUDA*!fz{h8{tRKfi(D42@4|8WIV9rr(=U@GPQRSKqR?!QC9RM7oD zQ!v$ZzhA*r*8LReAUhZ@I6k zbiS|L>;A*z%3x(_RpqTdzqhQks*3-|ng4v2<=&vrU+t|3)szLS%9_fc<;OpbuB@@@ zO8vf?;ONr8wIO7Voj9qo8vn6=ZfUS=R(b8r0xM89%g6twTrLIIR|aPh7*hjsb4sfU zf~EeMzFs{nMa=fAeCD=qV(U39uUk*=-t)sR4eHL+xT z6{Ipoae)RWmL%X%9eYt&TUCw%{L}90+BrT}8x|a2iY9!1KLlWns0~$>*IX3LQwVvg zR$hfvE6D3Qv^P4JQgv2oO?j0MmB&sTj{m${<+El;#GVOl@G-hJ5VVxsIDRZrxUSHo z!$h~rYU}2s%0$Q@6c|xk6ZF?sfxZkpE0R`$RgIqN=0@;ee^=#|NDr-vP>R`L0%IiF zR6a52udJC_SnI#WH@^VG8S-J^XHZ}PUvPLR7_6 z5C5jvU#|Z%@rc@LFkT8Zbo9i?(TY{*udPfazINEcXLhg##VNl0s?FHq*MtfL5$B(Ah%9{!)O2v3q~`k}-4m%M>7 zkgwt=TwwJnaep69;M22`VAztp@W9@>kri&H{)hZ za%&O{No9@5si+eFLAnNtH46$=N6qv1uzYS0B}erT|Hhm>tSq-GE!9UUbUI}XyB11@+a3Xe{`7`(bau?Ok4D`_$N_CObyQ+4krOe;(`JQ=omOZP0&S(Ui0Hi%w5yvK|LW3U0W5i_8g>)CEQLzbQ~`G+3ly?L$8EgT8>JjII{em~s%Utf-_lRsGCU`jrQ<<|%>Z&G4bRHVx%@r9m{F zH>)&|S5uoeqEH#B1fBEqCe5l0&-X#gdZ;lV9P(LRRL3*)1*aGZ+7{+m{!t zMg3qN|ED=HVCDT)^LtzP|IScj^nvTt$VxFk`2XiLZB}K#b4#eSYErEd5vO+Ekgh{} zf}Ja^vZ~TR0Jb$$6SN9tuCRp)n4`SXy1KkTsIIQoAIvMS^vhZ}|NJ}=PF`Xt4JFH) zsL*K#4~wAr9Tpr@Q|_BrVAbHiw7Vk@f<75}4mnLyZ4HEtMM%qRWM!ZZF2Y#Waq=Wl zo+!}EmrHXbW=asFL6V+%nBV-b?`~~vYoQsQd1XFjV$%FNtX*R#j;V%M;m!jtl+^!m6|7re^;WuRRgzjQ3}}^4 zRV;#6;HmO)vLv)g^k)Xli>z8&nw%{uWTB*Lu4sP&vwuFUXf@UVPFcUUN2!@6&M?2f zbUrvzc6{u_5;$FsO+mwIQB2PC1(o%tG+jZzldUlE>)pJF2AnE`^F(Fh_gIO}JW&#Y(xSFc@*VR_Rep+RU zRApdzY1!kBn)YnOenIboro!8ilxAUITX*=wL3D?5+*|}7{li$87a58!16)8 zeB!S;Ca4BZp7t{8X3w;$`BfPhR#jOVQ0|(87?@pIM>h+`k2BWsawf_ICwF6NlDs@< zy-b$Mz<7)bCOv1rtU?KYT^aHk+H$NF{z@!-j`LnwBWo4h&YG&)(sEyU9`+F=(>q1^ z5~C)wLZ&zcrWW-A%zR&Biv)?%B}?*XYDKhjQ3d7-JDmbrP`$Nq9a4G~s(oD-Qx%IF zI$52DSOr{Op(>Ocrf1&qwb4x3OCGZWZJoB*kOmPn2eK@U{ol@;!cYvj?Jb;B7tCj3L z9SJxY<7$fGTuquqf1rQ@)vUOUj>KAt<+K*Q$$YMP^z~u-v9O2yDBz+dMX)Z^oumw< zIwp!kA+16LhSiiqA>dgJ?cdjRsi&9q8)!k>*rjIRut!RIK)U;J?vB)tCqVswTM zq6v|Lq5TKYuavEmyTHj5m@C_-v6VCE2gn8v3o1P35v74LsJ7Z&fm4Mi1MHjQt17TC z*|6z%sTTUh5%C2Dpo<+So#S(f!hi&n@O|aOYAWGiaz|*%tfZ@l;SF-jh<2)~MqmRx z(!|uf#?a z=@4eooJ!wZ45Ii=Bt1!;aEJ!0ZLM_@6BtkUir6Q>+2zjE*$8`TxHB%7923SmWNd1Q zPlt}DGTcm&8*H9~hNw#C;)sX)Rg9G$4cQ@6Ww5~zfzr{j=3wh5+q80we*eCSG}eHE zegn&p1&bz)4=?qr(N^vFoQ-1HAQwfsFXhfYQq-?}5Dp8Hx8=|Sr7Co9^zlMD`=Iyg zmO2AahXb;`Q{V+|L*Pa79l<~x>{YG*0y)3nte^#fX3c_xb%$lYE;axz6RZ;)cTqX* zOmU5ZF$n|%&Psu^uQ@(em{dE-UmC!&Rjsz)BX~yA)&jFhIluxFJWlZG<+C8@xVSJ4 zdK;sb7=J-a=UOrsBWeo^X!5=+GTEYkcmT~ zykRqxt#!^vtfUTNT1c-QD`%R-1j{hfV(+lBgO6EbeREaXv5Dw}R%gQ?VkF&VM3u6o zq+IYXy9NU@700!I299GTUGmzFx@on>nN6Afk|ug%?SUciL!Es7iM}AZRt9TQH4;-c zm{d^aV7Xf*H)l+s*hhyJR&5qGh5?=e!X!gJRh2cqBr0_{bqt1NawX-Domi~&##rEB zFlHzxXHu=+odvP87+2xeq)pK%9Hj{~b3Ct8=XcH~v$VY2SSQ_F+1oiO)eeccIj{nb zTkGWUgro>TO=7LVXwY0moJ8WpWsq_D0=IEuiPm{KcBTHx0MD^p-&Fa?(8m$n4s)F> zhF4RC$yF1m61iE*N5`RaQuZX;MQb(=MYMH=1+`#4LpWbh=2mf?;ya*;+JNJGkDHk1 zfXQCJl3ze?VNhq*+}>q%Ar1%59)rFrYkciopMU%atE6Uj4g5IEDIGDsB#+xVW3z(_ z4uOFKW>f}om|iE$gJ`X6c}uH$&l@z*J8%HoakB)uwhm_mbs>Q*633Qy;DBDkD}z^A zH{fh!Y^~-Envq~Hk6WI+{)$&gSfehnMh&n=U24hk6KOg%NOhvFjrK**#)h+GQsE#+ zAyip$X<43(5}U38B}=~4E-$aPA`cV;)-bFqz9Oh-2%aqtaR6cW#Df*=#`By4EhnT9tFhNjQ{uXsY09(>N+o94uhgPcn?$`;9xQ$pfm_T;X*j{gIT|Kl zZ%C!e*SpgFMM2FU)=3;_VK3w!nu^tP9c}(JVfDJ+>V@waDSH(P*>_O@s|}W2p6_ER zsjWKSs)4_te&P`ChR0vn_RyrOb*s1dLdfpd}Ggn!bRM5Lux9(P%W0!%-Zo3$PF*S~wa_dr30}n9?0TpO0=lJ|VUpX5J$nOxt z=TGuiR>N(YnM8`n_>sku^ClM+LQ*GWuvk3hw6NlK4fTfm=@8?{b9F9ivz-Mh&#t5j z4l9OQbTjj6Yq)Bchj=oaheKe;JApRS{mA2wFL~-Ly|>jhRM0hqAAID8FFJGAhOm~w zoxv?*X>$v#UK7+lE5MCb8Gi79t>SlHuL*fw1N?J{_wrX*vK{kRTmEXDZS~Tb)pM-s zIeGn@Y{2~;IBm;$r4?9W9c@DAEW`Cm?wsklxZJoueBlSdJUG(Tm2iq6EciF3lpvGx zg0AHjesaQ(WPv2yfX>xFo#BKAf|4~wM5{~b(dDVLJe8e>Pr*s@uv|XVVC(iAd`G@* ze&eHdLXXO@rAdrC_chx6)SK`^sKGeE!g+x{bu>CtKs^cI$1)t4<9Au@$I>CC9Yq5& z3$X(##9mE%t*#&2E)PLcD5|M4I^RTZ3>5J zJOXEB<2|EXzH8)sa`!f6Avj4Vo`gph#v>FVr2A~ZWBrp+wh8e@KH_hD9zuFO10FEj zh_D%f51YMTI!2h#t#lR0jXM}u&z6e7QMk7o@xCx;OVIIN~gyjfp5H=t@jj#=2 z7s76YeF&`x2NALwEvpkk9zsuqK?oxe#v@Ecn1v8TScI?);ckS75H=xfL3kbEeT2OT zEeHn?G9jT{gf0l(5C$L&MJPg;j8KlS3-Z{5(1LIffuGlp$CLcOu&fJIQqtRzKFLVe zpsw>F{(C4#Bp;@`-iiJg=?*I_i{s1>%a2V-pL~~Povezb{2ZiDHPU^N&Nb4*kT&UG zhxAX4@;@PsXLsep_AXw9@i5XKBaJsJ-17fHy2wZmUu{|E80nQr;}uQ$klqHQvyJrM zk93GB`M>O*`@UrQ%}AeOl#gDUoc;i5vp?~a^6!u~$M2Wx zFb52JUm|VlTd(!W?GHv8Pe99u{4Gb?l*d;{I~IfGUp-*)Kk>+i>6ah0tkaD22S}Ua z+l;h1p5LdG=RB0$zdWQ({Juz=@)?daF6(gHpN_Q2-=SY6>-(t>C-<*6(#II}`y-9F zVqAJxq~MQ0+SJb(NaKAD7r!c{{{1QSA3+*oa`B%?Nk5m8{vFch`2FOOiXn!%%roP^X^yxm8)K8s%p{n#|uMq|Ny}18H--eJSZ#De2iroAiHy zw5dOjA#KjLvmZ+ypJhm!_{)(tU|Mb_%_M{AHQ(g^7 zcQo+tMfyY|{YXmsDWoqn%0EQ9myyoeh&A0vUxu`4&x(;Y*RR<~oBZ64v`KFh(%lVu ztA1lymm29^NZ)9rZ-3mf&M?x?8R_*5RLEq zg~}#AeXBvh9rStRG`_>QmF790C};Q#A>?8y!K&phm@`62%fKe=zJyw+VR=66rXf%3WPmnzT1AENOS*jQ(QPhJAp)A3{CtDNNT zWx)S0_*?8VKg4%@k*R6uKiOni&mn9@cpu>tg!9l|4}|^*1qj6mB?wgrw;?=<@Cw3y zgl`f0L$)OdRS15B+YweE{2JkTgbxw^gHQk&RUxcIco-oIa@e*K=MxD3KsX2K1Bf&4 zLK(uX2&)mENB9gOj_@7ANjMMq3Bp+jn-F#(>__+#;ilD=Rf`Zrcn0Bhgd4FR4A57?0pXXhL`h;aP-N5I#a^MmQGx^K%duBgF5utbZe%h&}k32!j!> zL3j&gUc^BJUa0v4!r2(J0)z&H{~&b2zPc;IB?tuwn^EUR#B0&-AmXLW1H2V+4))j& zAZ$fA9qoO9_!ERU!haBcvL15`^{+yF9YPhtVuUpa4V5jG)gLD-Ej`9aI7L0E}U`w)0UxCh}k2yY|&55o5dC;iH@ z&PC{tFdU&6VKPDm!aRg!2=^d-iO~6B$Q4XLLl}wRMVO7S3Sl$CVEEo2!aqI{KJb+Y6$lr>-}NEfgV5&*@Pe=ldOaPw`Y;0L z6X$plbdq+5wt@3^J#_C$1lq1m(6c=V-$H+$hpuqGE<$(@Aqctu6}&%(G3LD7hmegi zvmv9KAd9~vw198UbJG@fz+CKWwf}MO9b0JPzyDU-dJev03r+lZJNTw8H1XR~SG=3H z(8M2a*fgiE!;fPNP5cEK-?W7ezGDkb{N?S?H*KMb|4=*lrY$t_9iGkj1SB#s{wL7} z0nXKM7U1&$_d&=8+)wA{0v-a`gU|^u?H=LIfUiaDMd$+fW)0^7UIe%vAs=uP;+b^cJm zXCOZxVI<(bh=(AI2JG-v1el+W2(-tyAUxJxtp)gp+13L+)LKC}bg^19Rsue!Cu|z# z6yciybG;zWGQeCv2>-p8vUSAaKQg1O`w-y|fcZHCf$PWPki(M$5^WwcP}$1u$gcoQ zIT8K}FxL&j{{j4-&cE<7H5SbO3t+AXgtH(Rt^}!m}?Mu?r?=#C&r+xKVYsM%%1~zBJ$YReSo>15NGj~kT2pG zLWir=nne6p0dox^PUoSNj5;skddl)|#w27j_v(afGOvNng+5T$s{s1|liwN)>Ma^R zz8K>KTeleLzJR$d{{rxvfFDB4zCJu&tr0IFy$LY&?N11w0_K{r2cZQpb&vT!0IpiE z@;hFu)*+7ZCcykqx4Az24WVeVS`XNdyKYcx%!9~pm?EgKkZOG(-@lr!)@9;O^s4d< zL|hlAA&jn3dHiO+wT)lu!*t(mI)RAkn^MxtQ_|Z~(yb}!yq7KaLwe&=(u<5VPtcbB z9x_EZ9=N#({9UH*&Ezx*n&qkKMJf2pQ_|~G(wkD!+fvf+rlj|#q+3(cmR?8LU#{02 zm%5?kQrRNvym_s}WvM*#nGg7U3M@1_z#m2swjNuCZ}pU9(+$Gj=fDSk|v zr`(*NxfwA1HPZa;Y^68!gQ%nLJ`Y=kn4fodshHoC%^o978%@87dON*V`6chb7y0Ea z$~XBKaKAaqSNSL4jkhTurUU$x%YLqWYQh&UR{j|K{SaXKXsr9y?QE4Aru>^a;7*My zUx>KJ-T{3>9@k3wKnMBhq9SXtQ8p{3Orso)j!NMFmIPMz>;6$j_HhR?{+O{LV?@sn zJG^%6g}yJ2X*}i+9m^XER3j9a(c<#^Q{ZGfF0J&p2gH z)A3io(P4jwwH=mcgfn6pcV_I)_+>`-douPMdqTexPd)LGjBCEl_%d_dvBht6_~$Wy zI`-E|rg zF#Vht0F$4A{jgkVIR6r?u^NYd&!-xu-}AMG>GyOzQME+o{bu&-}A19>Gyo4;Vk$%9kUe=^n1?NF#VoU8m8YfTf_8w znlwzm=Q$12@A)qc)9*Q?VfsD10F-0Vc_`Ko4RgJ@M#EfZW@?!0jICj=Gr!j`*O~7% z%yp*XWJQzfOp}JW&U~O@t}}-;OyBCKISQY?)i4dyw<^;xeX9ly)3@57Vft2YYnZ;( z>A8vyeXB_trf(J2Fnz0EYnZ;(I~t~M^)C(6w>tL}MTfrC7!A|6s?jjl#I+jcn)r@} zxh7tEs;bMiutLN1!B%OQKG+)?rVrNPCkmhIK!`Xl@ zI#cE60_OfO2YS|bn_ANe)3+V0^XZpP(=dHnh)(cZ0dLgsa=`Cun11b78m13>dWOQc zfO9$FlX9&C;BAD44+6eM!d-jBo7o z4ERq5{G|cspq5HP4hHNo;OPc@n*raWV0>HFQ%3$D4fs0)?gYosX{)yZk2c_&4ER<9 zUSYtG8StA579PGZ;1e;BXp6&X#{DT3X1`41lIOiJh zg$CT)fCm`xW2Uyg3D&Tm+5$ojyLLfi;j2cc#n=-bbL_9*-z>Ab=*_OLv&oE@g5zw==h+Hv!B-O>$sLS$5VA&rQ-!UUZ&$UI^L+`Ejr$%<2^cV(eXhY zXFsFc*KtoB57BXvj;HFlO2-RyyiCVybi7f=TXeij$9r_#qT_=)&VE+6uj8IN9-`wS z9Z%J9m5vwac$tpZ=y;=!x9E76j`!%eMaKtqoc)|`U&lRlJVeJuI_C2_qW?PPb307) z*&W7fbi7f=TXeij$9r_#qT_=)&fcus*KtoB57BXvj;HFlO2-RyyiCVybi7f=TXeij z$9r_#qT_=)&W0~S{=4Y7r;dl{xJbuSbzG(61v*})LBMB`86HC7R|vmGz-JM| z|7kL0$9vb#xVg+LmqB@J@V<^$-_4gMU%xr%^QWtn`kG-{oaEaG(=>rs(%QKLFFkVd zg@EaB%sXk)GT!E`z&2DSrMV)`J9aW&%Pg~0JO@`(dijn#B?!2BmRG$3>GRIQg&mNX z*H<&A61VQ*Jw4ou&{jCfm$IgC?$v@Ui*TV5&62aw{Rlc zQ{y@jbeO}p6VQeFX9ow@{Yn=p`}$p0>Kd>yqjJV#1$gET~e|%%(p1VjD)q}U60qe7bR$&MK&jo zy!UUwBb}@JSkFNKrO|~Gi8=x|8nC3uxfhjJQ0bdKMM^B1Neo;LHViLh<9e(bTs?q{ ziM~>QncSNNa!xaqKD+|0u7(2dhH_2tmCY|R-XXQTx>pn}Ut`8QryLLC5;U(|z`#^p*wXei1Kku<+t;GkK5M3yk2+)peG)v`h^HrUGwt^5Qm^N*Hp#zXl4SvMS1| zYHR7SCHDFSvUvWEND&wT+f{rY~4mhpR%pvy(J_Sj~KSc|Rpv>i};oLyeM2 z>^R2UxtqYv(>5J9Czs7i=>YB%;eEv3YF{hlQ^tWpjBAS!&kvLZt7gnst1z#|!XN_~3$9!o9SDYIc<~-O zFZaa4TqRtnJEeJ*v=@UoJ5*=&nv!P4$D8EpniCG1dY3opl7j-?uH(+#A9wfdw04@( zH%hlxtXk5ST(^hh-g(^~LZHoc)$L*8{d&0+t-W%6W5W@O+uqrG2=VNMCxT zyouDZbT>e@!BKah{4XwmOr-!7r2@8d5nn2{)?41_k#x}{d>nn#q+-Zb>>q!fcxqGa z-h!Bl*!D8BNk8g3$y7S+U5TjlcA{MImbmrJwIMX~S|{7!Bw3R*r74!B4TgCaUOQ~e z#VS=hS8m8_2LmJQI0d{nuN|!a^`-Rf(BVW%+(g*!&G_xqu50JQzIM>v#+(}m+re|l z%J!fg9MFObY1~!V4qobwfbF1xT$?K!+ecL+FBdr~wM_nh47l$l^~zLk739LcwD|f) z7Hw!`HvX?G=vle2cMMcNmWdHP>ksJqs9{h=$Ib}9tn-D=N;+b8L>FL{}j>re^4Wh)Hn@o>X!5og1 z`>N=si16K^puQZAk#v^~b;n)(hq=rsEr0FNNpnFO%oO%3=D*W`UzwW4QyQJ^T!F7n zRCK1k2g}0)R{gIvK$Nw3fKsS#dnVCj2^j^&yvM9&rgHOy4$*b4>%mTf)9eqZ0W4z69R+?jQ1~7#?$6#0Tz9N4N>kr`BuM&qO>L z!RsAAY?S9l&xCQhz=-h7))7CXvl)$ey^}nXCncjx{q@Ot^3Vga@EDssw0EK|_QKtr z7fj%$(%bkGd4|mT*YygAX?c*)sgfzrJ~$~kFvlg|Mmm|lhwyAP`MXkg(n&iNvNXNp zbOsOLaq6y5+uQbcUzMV_Kr_Yk;rYX1Md6t@v~#&HSD0M4j`J1!&WIND4Y#bpph?eF(Hb*j_3 z(BSud&-=Xpc%S4}ojRvZojP^u)N*h2O~Q}$<njV#E)os<*QVF z^wqowd-!D;jJaEWr9t^5*IxDIZ%SxYB?Dp4wJ(0yq72sVOFql5voayuVdu%dbWGMYUfL{u%P&6PWmoeGDI7ek<|vA@!H1 zVh~Q`mu`+2$Awh+@OXIN{B|n8aXJtZPK)Q>J7Vk0&peQ$SH3*FG)VcPnw4;(d`R9` z`^ral_QkIsUO*&2pYkL8Gx+f%l#;_MUqJb7)yQcE@={xd8LBF#Twv zY^i`*=8|prod<+Fe#Gx+9Akd(aU5V?7-Hq0KK*9=8;e3@A6M27_zfGRZ}|e}))ETp zhBP1kyW(HI-%wpO<7B=?0hrfO_@^8XH8=k%8%g%=nBnRs~9sjH&bq;Ny3IkH~1CH_U*|vR@;^fo$bwqh6)Amh@ zll7@X!^vY3@Zd)Nlkwli|4Z;6xYx%c6ZqpbAiVmuZ{7yCPrluenzBE>V`|H4OZUY# z|71ZSzma!3!Zvvy-EsiF6YyOF6(XO0>&x4!0b^q;OkIyvh&vt1Di8NYHVte7VCsNz% zohz3?`R&v$zdI}bVHr4W>{PXh9&7YJ%aYCSJM~{-wtA(MBMWL6ALT?2^3pNG9>1hvP|1VUy zIS>ID@jw3u{0xBm4DNx@y1^}h=JzufW98sLq8^~$fa6TXp#dEbT_@2#jJ6KWoD&^FCeG)3J163|C#f#SZxCxOtO;&5(X5T6+ybqe@=k78r)H@GvQIO6{f z(c;jqn7fl{8`C(@Imq+w!%9Njn+Z5n@}Iy3!lOD!zSU$9&i!*D{k;kFz&(|STLK)~ zV+(|dB#;F{Q@4QicuhxWds1JzvljbZREKUSf%{Tq-)$6ePNR0^RKYzl+77Lax$gj8+=6ZuZrm1#tt7NP=Kct_#-+9M*5LWaWg-T@^`p)NiTrZO!cm=^pdVU# zjd?@=h`E~>iTF#!$+?$Fkoz@A1EKGVLc5DXYtS2R8;3)+;y(V0nAg5X6ovj5+7mfz z&uWr1eV3AX?Ujf@WkXRP3<~!`4sq^x7`e)&a5U2Ss9l5k^I)1I^|MipT^k8U^{9U!!^X;1nUgFxm3 z+2*D_9k1vGY`^GA!LDyTtZ?uyaNIF^$+<{I{S3`QOEWhC4lihlxpR;V8wI^9;uU{abafv z1xt%VksbhxL(N$T0-;D}32t#Dcxv}gz=a1M-^7klNJV4D)Vvd^h_(bGg;@w!Z!CN= z8$xU>T-BMfgmaHEwVaES;W778+@Xp0a6~*1DOm**5U2k)f&C2(=oKzTL|jYmbmOT* zNQk*jhU|Jvrtrve$re3yEOV_dY5pX0F~(`mH||~zR5x8T2eu$g^o+6m!oPhz@xgVjBt{JqZ3h=8gwoT;OCOK+@TWpi9fB3}0Rx z`Y3u$2}@t_sHBO>Gqnz>#i7rl;}EtUf+6audzr8c{qldss^U`$H)8}_w4TkH(CX1N zGJmS}DFu zv@-A(5}km%8FF3$xzuhwBjJp`=)y&zG!Becv-#LS^BKVm;RuwOPCO?Nk=(CP1;{@W zGZ~E5JJ2tS!lRA}MABconyfgvIa}zP(RSp?SywD(@ZP8%xGxpHjvyc z6ZFC;))!1{R|;1tSfg+*?w5Ig#6KE>#oST2b5M%-hp;X*y#9#5)RAStJZI_2`7?8pHHi1Ulm6 zpF08b$``qp+-A?wqBAMjI#^b)KZLm5%E|K4n8EHyyu~CAem&-1hiGeW7)%Ppgu(dt zz+fV|hXDfN?@?OJy_H4F9H<)9s6@;yBZr8eFq*4^fz0;UQn8P;I&;_s!lNjC2eQC? z3#zu#L&-7$hi@nWp{{pWzd*!&0&N>}A0Yq(JQ`W=Hi&20=+yg71{XXSP1hO4aw!Fa z<1ep+`mmdrKLdAkH)VYl3P*ooYe)QRksURWIo{L4+W#Vha0Y*On%*$Z*3^ef*9kh2 zzZ2aReFFW=e~{#L$B4W?lDEX&E+XNQNK z3RC#j%w@I+tJld2O%qOEb-64vo#?DHB$DwCdd$qsL7N)jiPOIVwrJ#sfy{#Rt%wG~ zJz9?f9PAQ^^yK*2n(<=sxN-T>w@+7ox${ghYw%ns=KckDh{tbk!jzt8AOmY#s~KyW z5LmQhateuhPM2aj1VV+_X-OX~D`WJTi2olV_)A6yy={e$U?lR?avAJ5Mn8lc*O{R| zd~o2DlAVp2eNr-?ZoyDR{ufSN7cB)z;t&;?8bvckUzHkceF0O7So9UGPQ-tNX|M6t zXuFv9I@DAJ>qkWLmu#Sa!Ax#z^d;oP1Z)FpxGz5q4_b>gCA#2H3_b-{u*w{K*d8(W zWmXOyyaKrFIPPht($F4}$QthaycEpGw2z~&;T7&V&P>ZjiemmoD;gxK@y|t29Kpyd z9!a-lW)PPsqIR6z{)WwX;A3vF;lQ7#NArzk(AIoyj_uAnh!@9p5JimmJ0P$Nfr$Tq zVhdjwTcG`ksj@vYUuZGToyEU__MQP&vS!GJ#jfDgCF1`SgfVv;^F{n22H}jW8MKoH znR|*H!#c4YPA(LJXfK8l|KkzK_7DSgW-5Pt4-U@k)uPZlW{c)M^t*-JLKy`)dKx({ z5;^$2SuiX`P#jLbz{r7h5~kJ0s_oh+Kei1rh1h|^-8&$9>pW)hA+}gz{bc<62~)0; zP&B%@fQ0Gi3qALyKE;x-J;&`cL1Rr<)HPJZ#1aepCAo9VOyn8S_G3ode`6qe!u$ep zm}=`_6!VoVP>ib5SaN7xVfHRs@nO{7zsDG>Mszo$FzB{PhuyTK!tz7!6oq~O!w0|+ zn>lGtFc+ez$m0SZ)MGXU{=XoQU9%zA3w#oT(AMJ6S2D71^D+txqh@8~fBC_8Ub9)KkKU3=A{);_@<3$eO*8at1C7%?R!9|pn>_Gl> zlmGMUB>!B{a=_h6Fwtc|O($WyBXKG^9scdEM$QJX>7uXbEqU6Q)+Vv&s4NZ@F2ybmCblg_p*M>|6<7%`ScPqYNQkvY>tRK{h;i({ zQX(p%mqZG=&3-E@N`D(cgwtEiGS+0_{=H=RDJ(1q%Q_8vdwZA^DqIOJ%dbT=oLhUHPjzoL&l%Q+_w+`%?pwv{Ta}Rcz*&6 z@ir9R^FgMaZ6_N&EQCC>g-2R4D>;ol`(gq($pCml+y|d?7y|qMcifRwJ|qU zNE;_mQJ4=1*$ateHwoGMOJr|!KvC$Q&|RS!Yd449B$<-sg^nuvb}QcQUU?k(`qxT8f12Y-Ur2!ys|HqXPnr1gB53+787vRNs^ zTZquEuzLbl-$K-w`=tm>-NxLffR|c*E&^@J9+4_}){(=6sNgiAMxS{YJa+zefyo3ES zsgzg$v%nw(cU)bna&uLR+uGjAuC3=z+2xa3L}e!hRbE*Kqpr zmon%K#$CxS;x=PE#(q574Xc744a8!b!vB+LT5MQii4b$Y5WIi4q>k!S9QuNmJ@_TF z-h@8`qBRd@_9{oCh`$!r6?3a_$Kdk{XnO=g6S0BTl^bYl$&4e`$Fd)~vn2E#=3`83 zTHnv3Pg#h*jaB217?81s{1OlTP)sM*2G183vzS!e0sNf--OpMBAKa{PszkW0Gns`% z+}Aj`)5Ze=`_Ewz&V80cW9X}xn{SfOWS|ckPBlqq2xWSn!NlMa(hCeG*CvTG#T20F z`;^99WRJdk3b|(tFm!!|Ze#2<)Tv73*nnysiE1(9_Qy#aS{Hp#!mZJH2xVYQuoFDp ze7OYOkb4LVvKGG-oQkUbQ#u6d^d=)=cLgj0$!{C;$9hK$-#+6^f7MW3WvE&V6?Zdb z^D*HWA}3z%bVC-h%oYl>U?VmPONa{Ro-0FQ`nQ~`aND~$G^$TvV?m!R*d^ttVR?}Z zepIhGlEH7BLDR4v4u<0e=Rbwq!x_T}ag_KEo+<4mPJZkoSV@9>@n@W}tMUds@e|Vg zZncPF2B_soqLYZYhbN?7C#l$8aeWD?L1R6y&{5(!FatV8*y@_LT@^c7VRx6AkL=4m zX2w0cFLyigqRt(_9OEAWvwj~4eT-d5zS!+3L|?I_)H&CcTn}P3-WN8#1BN2ZW1Y(LDuZ>w8E=h1Q840+L4DKK%MckpX znF5mUO>ze&W8aWHgo1_BzXU>dh}q@M^J2R_g1vYD>-5aw+~10W_6MQzm|G(a^-ss33|F|2wz1MX1qxovif(Wu!k z6w8K;1C6-cU>k4haTbCEY0aA!u>M!S$~>fS3ucFA{yz+4#gW|En5)SwsgKDWxsvc_ zF?TT{F!;Bmui!liyw5-i_IS*xIvVOslY~e1gm8~N4o{YTNCT}mvdz6tPG6IRMeMJDt1Q}R{ zNidJYnwim5Ivu%CX-KHb`vyIO4UfuyCtc-h(^Y<8z+ROAi-B;4@P(n-jliT~M%^lD z=}*$1MqJK!!(x1kUkYUMA)5a^rH;9q5#ucLmX^$?i6JaTvyqWS>uI`eE>4Cxc|056 zynjYqgzOUC%PbN9oe1nMQ8@iB;8Ded?S8J;pw5JpruH=Spz@Sy4;1xP=CndzlpTgfV33G9@uy9$eZEbgItx@XguD3(seb0g7!+|2PDnl0a2$aqE{>FNC5>g! zd)Td$)kQBPLyLurcLgV-2A9z(;QgGrticN00dxZiY9McRq$0kA)A{cp7y7a+EB}l5 z;`f6+@HP-1Lwzoz%mO^1$EzS85rDswAqf7`!c-2m@{vTafuDOViZ0B2VHc=>fC&|_ zuYZjQ2DImBTM-?%U=7#~!zRUjCUvWfW=s`fmLe6kY4o8PHwT(u5B>@aFE^wU4Qb51 zgmBpHK1YPhg&i2Ryo*UM_5%px`2*BH;Jm-kAoN(@I4A?5!M%6{-Oy+X-WG1j{V^0$teS-J* zXMlG%0$7)FI@E4S+m*}EsFi#K5m{3BpFm5=3>DLt`=u3g15$4{#9=Mc zbF>5*e_?>vNJfCoG*dD6XNA4Dyj>(E?ki11mQw51{eeCYovo(+E*s_5!PBgL|peaS@!3y zWgo-y2FdXy6xBWlmR_>Mfqi)HX<}dTBk@WLHAK%&J zaw+0JRV=~XDAmF;Xb|8fYgVVCK8s()h2Nz#ZIM;}USm-|D5W^mh#t$$jWbO_ z?;|Vrw}cZ5dLPO~K{5ArYPq>3b8#)$Vu{AuzW}nouoO_pAR2QYVot~>-5%Y!l@Y*f zY46A#;|oWA)7UY;>4((Dhfw`DjNuNbXZ4TA9nyj! z`=dzL0TGkbA2o=%$BFe~$c*@ROI_grzCgst_dkh2z8%EH)&)+Py1Fp*4YvF?WnOa* z=abl1HYNT?NI71RG-Ad->4@e9lG~Xq?^y4(OJ!HVm_Y@KLjT}0BQ$k2M%Vj^_sN;vrJOjFXr;a$`dlL_5|}&u(eO zn=G?ikan=7eHMES#UN=F78sd}KSzULLz~9MVFcdj8`0>8ve6YqoD1~OXV@#1l(!{i zLveWaYSCZMMsemqLWNa`!!C$W^7EK7a(!lVI&2Run1YO}8vD|HNBn;SQkbqm#Jrk> zO-pPy=YY8NjKbzm2sWN7)IF~Uk?hzu2{nYm`VXt-GB z^GbV8CqwR`EP)H&u`?q%*Bs0JDwMlB0ROl zv<>zT0UNCdgC_)?@f?GQ|0yCzZk%(bQ2!_PnvpHAaUDf!J%dUJ9&8fv#((e}CNy?c zk$DE-G^Ugsv8(9Yw~LxyO=&$@L<1+Kk#3BV_RvN0kpoAx&jBEFac05SX5%@KFfOTE z{+`oHxMl9KeqO__5yc(AW3>p_T;2OT z)J(xn5(T(i-($ookySW&c4smteE!Q=S~&MCu*3Uzrs$4>#a8@#*bgzR8z@9LquL0C zF@`VA%g_>kd~CWA$BFw;Z@iyPRfGzcf%`xs>r`FY>zRk2If%{~A(8+<(X< zI3tPx8zkI6z`%MWMb`ImIb2=F;GS*^H5Xf`=-oq5Mb<-*RW#lE=m~jXOcwJi8*h~btH$sh)CPQqX3|rF2}y` z1E(=lcspz_~Dj6iI z;sPM?VlLIN0&0N!T#2f^4UJ--@mnf3oZBM$O|OzF^t>8D(}Fis@bG0z=FKeynNROV zlN=5EE1*|9jE0E!qeN8qf3o<<=*Fz^celTQlUd!Sf?h)E&q2Vx8?IQ1J}Npm!C>md z6`MD}$`MCJX6#jwn~tLjGMhg@ElNWF#ya#i6dEpE)wKK2#$&>TZ#L~N4-RSC-6c4@ zsbv>B|6D(4{Ge$a(6qZ#;|X}ovk}rFaT|id=2&rN;kMQ+z}Y0~gve*ahyBt|!ad(b z3&CulAU;<{otHp1v_BJ%1?=bCe5ctWF zg!U&8$$c!B0gQQ- z-$Ds8$h^#=#1B1QjaV4Z!Rd5X06-6Tn$+RkcNjFcz!K=N&KK$2tFK04B;yVSss_CI zpdHvRH2$$t3>GD(oli5VOX%IKtzQlR8i~&BMRvJwk7AH$xyylIgZ~~CK%*Q7Ss+;f z0@El5F#(TGBYk%YD{Mo2h6sjpga41H{L`Y)2YA1NB}e?flfZRM4UR~t0s1EP53~|> zhB}16w3#&6WhQkU-LkF3(*oqqHEp^2657Y(xTCBKC2-$d1c-ylS%gL5H(ksaX1hxm zK@}I@E^U;aM>cp>AJv>n;UoSzhLnxU=No`v`gFoFFTyCin(5<674iRB1`PLVmWcLY z5bu(x9S&0L&^gmPU|?(p{IJ|j6? z$CP_SyK?U^+@566R_+Ru%JDy5?ng2fH?Dv2lIpVA(MOM!w?Z2UL2dx6%G&n_|#?`wjJfjo_iRc3*qgOv`UJIRROmDch90>;bjK*)5UG6A4@7)#@&*T`Z7{c zi3-{fHVq*f=IFBALeG$+Rc8{_?qON`g(u!Q!vhiSHRhgST5xr_^mp9B`SJ>KMn|tl zg!AEW-=!oAyCWe6`tq5Oz%E%%r8M00arwN*ruH*3o&&vLpoBk`V}hfpCahOPa_~=O zB;r4XLD)?zW3XUzacH}2g!M7lsgx$1el7w|JK9yNZKK#801lW}DK^VfpEq%Y4_OZz zCwt;f^lwLTi+WJ{40MFXahHun{ZBBhxtb$K#QpM0s^K94{7*8V8U$t)bJc#1gO+2WXQSXLs@M6*8-=Pd_=R83FAI`X4g4}gtjp@G^$h}hn z{~s8Hg4k%nW|B{Kmx@DIa9gRMPv<}w&ndV8jjg3@mHR1a*!T3<%>974!<4!B0ah!V zvB9*?iwI;{$X%uc+sD)TNcx}Pwu;NLF@Mezk#hSR$!;G@7JL_F;Y`FL?h&Xp_HP8p zxE{@AHt*`0z#hUqDeT_}-d~M?ZyAWKeLVQ3VhE4X0Ox6mZzsh%=w=`V4ZDAu&LH<4 z)3!ZC?CoINK7(#`NvD+q<$TPEEp~Z5v*-8Hl>RUbHRd+cT(RCFdtEPm%sAF>g2^bC zty3&#v6UQU5>{xHKo=WJj=5uK*?694+72&|Tw@#6R9pUI^!bt{Zbl1I9M}CEz{F z@LmWZV(w+4Lw2w{lRRG(>COPZm|HD?zfp+HSYBn4>P-^%C)!}MG>N%0ktAKpKMJK{ zc7;a5{;){oKVRtG(N<|+vJ)0a4(>QzOr3J-i}}_?qF?_k(J7~a*iRQU=aDJXKp4(l zi<~%5f00yrDy# zH^K!jG4)==0A=jgiQ*7JI(7FCjuPQ?_biHxYfh`f7M;5^Unh=>j`d5?ms!58u39w8F(2>>x zC$pZOTi7om{*Tb=Qo$|K{QgB0j`GhFDgAd(l`^@%NHY%MP^Ucq2qB$}BK}7$hx-f% z1Dk&PN0ZbQyv%$K`!P}gyYlc0!4v0uAQH~s5s3JIBi+Sx90pg9#<-g5oh4R(oB58wHHc^xkuq%7%AuzL)DP@fi#iZ7nNx1-W!=Hy?-|ANH-oxYDRzv|d(S%qH0ZrN zYU*+i8%KE3+r48Dz4cJ^Fm}3zYK~$nWQD;6nUy2rNn#eGa&gBRY>3Z8gJA;J4femiC*vFC05w|C zS$zlgj{}iAeUJuQYpvY|!^aJN9Sm4(zu?kT7cpfA=?NPh-R7VCub7-)+`*gpC4unEsQq)7ivvW%G1-I4T3Qb4mg z>wRZu6kZ&9DhmPBz*FH=1K3dm(fN>b$-2ew!(bx0AIgRi*UMi)hD#s=w*64kSJ^i( zenAY3Ula!KbF+hSF#0~`o{Kmh?c>S(I6mG#3)8_p1Bq_lCPpMi0VqmnqZ~F%kO9nI zBX#5!Qb#|7IZ~p`#hnoY&vZUyKZpt4kkEP_xIbaIw;1kXU!mqr?aJD0%G!dUeOZ^8 zvY0n|IZHrCzn>b3q)#zymjhKCTCtKG!p+Kk6`_sIs}Z#4ccS6POwp6TPv3DUR1FW_ z70t{f_gn|sg<89}kga>@xlHt*L|mU*nx_E3377;2CvudYx;|ml>H!F-2btO zQHd^E3FG+w#pY7S_YUIX_~6dquT$9w=_Apu#uvT8Zisyy3DO7V6QVCV?0gcs+%Mh!E^3#= z7ae>O$oBF@7o%{Lk^$Eg2pK;T@uw0}9}`lqvLcCBISwimuYzA1$gPA7FxR7>r&@Eb zrfTs1_5}KpM{oylxN-a9OAbODojwio66y2o1+6$loc=(6k!BlM7l$5+vXS=XO0FT9 zx{}}H#|tn+u0ZZZCO3OMy7nf+B&m-$*DxV<^gJ-hU$VY%@h3Rx7w>MT91O)iV0!3A ztd68({s9rxbjWjw9rF-SqTU}HPyP3a6wiGUl!e)!pkvb7v|~OB99lUz3Ek{GD9v=t zFPSl%`EN<2NGQ;ME^i(Lr|VrbLteq02r^nob=J zG!q&zCheFCZx_#)egR4}CY>i8$^8y1%78KytGmoroENnq4h~=l>t|Tfl zX;t)hn5}F3Wf2FzawR0$eygy^{SVloCD3e_Kg(tlf~g>Y&IeJ1i2qk&rLM1zm6eG` zI#O&)J;G#hp=XH1x!DqA+?`7vY^iG}A;y-vk`bJbkY->@Ef7q+rD_18r9{D;#2p6T zxgHC+#5WP5Z(y^@I!^wcz^k&?$gXvQ%!&My$FXaT#~md+#6VW4Jm7pMpe1Wor7V7_ z@o*q7g3Fe<8eY=-62Er>5C<#GiZT8hZ1GJ^Jg@DiW$BBBDDy8I1h8KvW&U(F3*(d8 z^oK@)HID8^{M+e?xE|kz2w#rC`DB_+*nhHgdtlxc1^a3Lm`#@GTX)N)tN33+Hq4q* z>EZZRA&(bf?-;M(Ve?S-g6;Ty}_dVt=lX5pMT<{Mkm>0K_ zh<~XtE^IM$Xjz;$HJtFuQ%MUv*Vr10&etMf9#dB1$v+w`cd|)EQW26o&0||8{(d^F z87pYr_fgmXMbO2-U%k}U=Vb+g>ilec(tL6xsN7h=q(w7B_KF~ z1%!<%FLbrFPt6&+<(KNxALVKh+Y;tE8ze=J_p|E5T@H4wVfht!z6UW95~XsYfL z9+}N2!_1212OO^$p>-XKwq#xZ2$RjchBJKBw?;g>|JY*I_Xyk}@W%{T-**k%+t&XG zL`<)U!ClgQg>Rt{c-kq|-i}l*iXR7WYad5|;Tok@i-Uq5MM}GB;_+4H;w$-!N0Ic` zF9!3newZ28K{`BtI-f$~eGwyT2dS`I4Jxoe*<62qPEo`7y>$lk{1KR*I9NFUMPh~- zx1-g~{CS}mD4hTH?VlU1zKW)luJ%`H(*+A*fySWlBPVQ}2e1_7lh?OFZ|gPy<=kR3 zUN0FTc?Bp8m+!UCa`?P(Mv z?CuUAHR3;n>M>pd>a{DQJ;;*(bjtQE7}cYj(8S_!&z(@nWdeT>BZmS-{6iVw*Yhx5 za2k$xyyfKOhcq~IZ1Y42673BOjW!~2qtgpIjrITxr*6(^;;8w$Xh)=w@=aToeG3pn zFZMxXtNj`?LFfk-sG1eEj;VN#WCpjjs8!5;&eW}fX|j0csC=FfW=!{!p3{Q2MR?f$ zD@MCxi8%%DV&6nN3Fn?_Sk?;5D#LQE=`S*eep=$(>3U9L7-FAb1pRtEHm2Vh4>=?L z`921HZv%!l8u4#E6EtkMw;7SAbDx`?N?WBnkyF|a&sR$g$436RK<5OXyfoH#*D%zz z?{2w&FZUnh{*&DKA)8p=RJo_gy`$Va%l#m^ca?iLxo64!P`P)P`{8o$A@?KYeze?= zk-Jasz2)9V?#Ii$pWIKB`vAEQl6$t?hsb@H+=t73gxquFK1%MV$~{l+qvc*8_tWJb zko%c(FP1yoE!KCO+{ep(qTJ7w`((LaAonS9zX*4>NzbQ-VuHH+J~*{V&&L?wVd9T4 zzRkoRVEj!JU%~h$6Th4B=S=)g##fp6ZH(V*;#L`~wsJaR}m@P5e8?*PHnN7+-DTUo!r%iT{`JGqa)qe*WGQmN^ZTwR7=(ha!BqTJ-c+? zxcXXr|EZzjTww||2OAqE;(LeGRP9{zsqq}EZ+wLq7Qv6s+a@`^zIJxv*MM{QrD&;# zwpqNYIpt{QSwn2jA zYP<;_KXKU5bD-3sSv9r%CgRz_%8Ggrpo+w_{z^9$$I z;nUK{Jh2M4UsNMmW+v%K@pgc!W|zX!>Ss01MlVBw(wh^yq9I^%=_Gy;yRfFLmc>A{ z`N4_?$8<@Rv#14ZM&qOZC()ZEO z!n|QGNu3@)#faW?K`D)brTxv>T2u7Rok}KY!2H11~tC1rUtEicFp*T z((9MA z>HeL@hKdIJP4z@ths`=^d@*%GvxKiKZIH^vON2;qDmV$QuDWm@rc|@btKf?2;j(0g(>7XS zqR{{!Ro(zs2R|g!C|d=aaCS`zjAdeFJq$O8)mKf%iztATgCDGgW1UZL#^Dzp2t!$8 zJrMh9hKBr_au_z;IXcgNS~Kq1q;2^<+1j~dt7g!T%A{n1j9g<%8_G({F)bn*JPjQc zQ(Q5pq8jcSCPY6~5tPrc^S`UgDkTutapQw#g1=SrcndM~j#**;;`nAYJMs;+CuPPO9v5t+0mkw{l5IjJKbUk)ER&bTqrFhLa}@2&MJG z1XYyIExn|I(=cdX^(#|Bwx9i&S`j@RrX(`c8(ms&8pklHh$GB^oWK&w`w_Elx3^*BY89)n3VY#&3rG`Egp^l<1J4Z#NM zaHes_%?uN3C)SrX!0F94^S&{hJn!ufSfs2rAOz>D73%PFg0(j0v@06sBl6h(mDm~E zn4uL)%PPlK%r*9CJ0ZAg%O~_e3`S)z*6IS-OAsbmk9k@}{e+63Q)YqqG$o!=)KF5v z0Ttb(vI-Lyi}0;>zEo^2XuxW)K47N)IYXQ>=W+Nq#%hUl$gbG378*y5$t zb#P}KimS@v&D73b0I<|JvZ1KP)`i2`q#8_4+YulG+Z3HGhy^4}&nRN_{E78dv*Ar< zwPQtMOMuyqnJc4dILD78IEHXWT)fw$Lsu8{L+3QY+|k=P^z5~ari9>H25;WpDQNH4 zL7Ma8vk^BAL+8|(;DM`2qL*mEY8Q)%Y4N^He?V7)0z|hM4zRE*SEmtoBS~clnu&yp zg3oE!%_pA&(Z|b|LN&K%m!Lgsa!%MnXpb~I43qPN!TKD|OsI>TT3H0cxJ!{-1rJ<- zr9=V?Ep-f+i!~<%eTIq8>}mMS8Z^h(H*b(LrnIK4qS|MsXpS=h4)PN8GWB_AT+K9S z&>*L8o^$qD&V)(h5~sZFK}rV-yMoa9>x4_?w zsSamN73Czvh=X$L>U@|6aPHQ5;(RR1#N57 zcpB|H4yc=j{>R#(t#Dphh1oEXigQNm>(@80zgIf8JDIEqsXv4N_xng(Z(F1(5-Oe!j@uHeRi)3>^OkpA!Wjnu@?tLk@uRj@(O8#X{N z9V%}uvt>JVm&|fz^AVhS73N6R>Z@wRY%uezsjkH=wA_ag^%86t4vJ5^ zVM*ruw==40PPTJ#ukFzqpLmKeB)}dmxNIY=8j3oB|cQmPUm|0;3+VXqF<(U_HL}3Rgc>C_R)E;b085N z-ww!!v{vnTj$v~upCvbsjjgy8Ig71hqT+PRpB zj&UZ{Tv7uYaV&PsxJf>4$~Y#+@L@Bmg44=M>tr^9G~+F?`zaVI+$u32`ls zm4lhY9dbjb8a`~`=&Imp&iUB*8e6NZF$-&x$H&g#8)AeLz&T^6bH*^|48J4WdgN(y zkn04^jq+vYWadv!Noko+G{-_}kjIhRSlO)c)z0)GZ-Ya}R8fqHUn4pM_TmsjXQOLG z&-Ymb7ZG9siGEBHfUt^9#Mv|ydpi6`N#HV3z=XOAaP41QYe5ykk;CaqK+-G>a5cN=TLIXM{7E9IGenZczt?uR2U}2_%UE4>dok0Wp^>?sG z?TCAJ&`t^m1(H+VvE)%Bhf#GYa2K8KN+3 zHRkkf#0G*qS7|>ba|Vt#m1$sY%CN-`yXW0EaJ;W?1OF_SfjG`5b*`W7)X&yrXP_p| zp5x4(;~Q*~5g%gX`z+X3Iuk1(s~gn9Ntgh(uSKHUic1rB_;|eG!|*)23LX(!fpbe# z2P$8l)3=s?LoPrjw#W#d6~2Gc!(;ybn2rrk#6@%efC~EziI0 zJ1g!342|qjt5<KTVj_F0HBo+YjKGxZN!r&48cC(=5Ld%9W>Q5XxylmL8ykR4pIfDi1%o#F_M0taU zJ9CB((P-X~VNU&tPL-3_d+Y?WR_iTsdBDS{QA}^A%t21(a*)R|D$}I0wxl^jMi5KP zkZfUP=DXlEEW54Li^_%$aq`;9F=u!Jo~U8jWy40~`G+`j{8nBTgaU>R&l@((nGU|OG0o^FsMQordR2R9}ya3U*{|o+8p2qEH{LA$^?mh9po6r~dKY|fnDbBn@@aD)J&p922bqCxP z|9C?0r1)^_jeogDm3rkX1Cxjy;)p77vu7lUWoYyAv zx4fK`UQTLCX-bEb6elI+kb~0*pHsKoaUMR*aq2)Y9seCqaGWv>qLtl+hiW4tL=7zr#B@DVIa26AyM$ zcXf5rt23OGJ2RZrQ@S}R7j|_~~eUa&OIR6kQ?Uh5E)b|f{(z+jJn3^(ZHDUsMFy{)c>L$PRboUoYec!F8}N4q?~k&llJFh z@bckFPWtEpjzdRt868WSI$hr}l72(ljjXEE2mi(RKYFpDe}{>@EPYXv z(2_2Q|Gz8UU8Lb<=|(rj`TZWrqniysyk={zebB83W}?!a=%rJb)63_KrnDQ-Vx%kJe?;jJm&?kn zbgW-B{;yWLIfkmO{m*FXczxWe3}4#8CZ&hFFqh@4Aj@Bm|HqWhr|J7@haJE@pmcHf zXZek3s}Jqq*c(iJ_Q!7&=zgVitGwl^T~WSr(A}kUzuOPp^`Pr^qbV0}@0!cXm(V|G z8$*@uV#MXLbP45t09@lz!;gKh9bKTUzoo&}*C?I3&%}0#xAOqdrQKxs{n5)W!5$`p z?kc6j%f#lg@+H*c3eYW8I-i$LVe0Q*&@EBAEA_4wmT!)LgWu5El)*w*7QrQ56D>A1`GU_E~I zfZ_K(oS|H{zMgs{(=Yi@zYjiU_=F9YHn}|hgY?DtPk-FdZ}}PYw1Y>Ke*FJO{aHDm zdD4{oowr<%|2R;6E1xoazW26&lKKvL#?YsxX~9;{9zR4mS>Lq382ame2K~dJzvx9n zKVR9${g$U*BovfB=v8%vOLy-ly&2K;^gj+P+reRb=732SS@ChnRId*FJgNB`FoAmA) z`ZOG%;Rp>2G#sbl6b&mi3~IPg!|OF%rs2IBuF~*14L51{riR-z+@axa4by6joLL$k ztzkb6hiRCnA%8EE_2rpphUFU8X?TT(OEkP$!{r)2tl?@6*K4?0!w)p%Z=93=HyS#% z2JWh14-NZhn62R`4FeiZ)NuJalfOm7Z5nd&%W?uQnsAwhSuF-0q2VeGw`e$SjlnP1 zaFd3UJ@&_Sc0c_`5WhZzgJ-!v_v!&cY-u^at~dD}z21aB9A?5EbtZgS)4O8>h5R4Z z`rGtYO@CI?-&FeR4mb4t%>(AM>FYK96c7K;HGQZj{R{}o{9%>T@>zSNNnfGqTeaMG zG~I_h2jRcRT0^%{>He#9bgvv*eTv_l1m92bTNS@k^TXxv2i%-&#eb0`{|Lo@ulTP# z-4U;beCGmD=^Z746GGmVI6<=U4dOq5ABp z<-C22$?vu6Q9hGC*(29InqKZn@6pT9SE{~jJ^E|mADwy| z_!Uq3Gn#&xhyU2)41LIxeut*tpy~Zo59!$BPl0|`deY}>I)4+Ncq`{8n*NF>{aS4F zkd8lc&(P|*Mbo<~eYTdnP1E0NY){W;1I+)v(%XK#P}9Frddp`RoFD1GQ~Fbs|6`hd zxQG9|{)YZf9zJU{-3MMB@L#F@z_xdh@+FS;U#EC?uHonHr}GrwNAbz}(GlR4cv<`2 z=CSXrm8P6TTE=PLl!w1rPCeLmdRF@pKZnM2tFMikzFE^JX}t2mNHN6>&W2Res z4@@xdxP>MxQa+<68F;0pPuBE;^G*6ZO`omlXIx~`cWAj+Y5L4klfI(Pgf_iXnSuFn z%|tnIv|Hd$Rll~}yUR`b*&cddj!D16lm1^#pEu9ot$+M_l!24^ksj(te2*A9sA|6# z+mm+f^=p>TelsT^*`Cw`e=m-q^%v!*8Q9`4(Ry}M{aO}BE6lvSe(rjtzt(r>pG-L; z9yOuiviF^Gu&)O30EcCrs^#9Ta&FahYhMrN89J}r^G2KWWcssmEmL`Zj$D-IJe@yS z{p~3*~W&bbAr~bYD zfWOAW`g{99-?L4+w;%kd>B;nRvFfGAV^_qncRlcj9(bn*?x5>T zD_<86oaKS-y42F=dhlaC@I()Mfd{thbjuG%OWNu41`m9<2Y%55+x5NW_m&6$Uk{wF z{@>Eub*_c^y}iWt9pr)S_+{zscw*seJ@mi#z;^v?>7VuB|K@@1I^WXUb-ab`{(yy# z*Y&)Gb9KFH;jtcgx(BZDz&Ci{s2YT?Qd0@NFvGm94{NBQLePrP=9=x4bTfAN0 zS=i1uEWFy2|KA??Cl8#Z^Ld;9I1gOlfv0%j86McK8!W$O5B@d}{D233(gX8T_KEHH ziU+pq5nJBZ9(;<<<1PLm4{Yc87N70G+kJA2AML@Hdf++_e2oWQ=7C@Ez;Alse|g~D z9@y3OxRq~^2OjT%XM5oJ9{6?-{DcR#>wjBb&xP&VXPgI~=Ydyx;7>hphehrA+5Hbk zuTwpEn{LBZEhc}KhBn$>2Pk*5 z(pmntJ{GoNm7m>b%TfkCH1uiMPs4Ek#cv(EZ`j`SlGW=tT@0OSuahtzI@rNeC zzoGc7B=}DhpG^Mm6n|Wj{KsBxdDZghDd~d}c zmIOas@m-VP$0$BC34Vg&lj*Ng@uQREe@O91Cc$q|e6sd?NAY|YBk{8K@qyx#+3zQc zPp1E!2f+WJ`0T{O5x3i!BNs|Ab z1K^)je6sfW>jCn=qxfX@vqSOLpIR}ke*dTVWd5x~v(bOD`e!OW-7?nD@^=rAzn9|K z#)+5Bf1Khg5|M~oJid-3_TeVM-=+9u{r3sQC+nZ<4v_yH#V2dO=mGfeR(vx1Ip`Ww zzoU}W?|8*0(_cTuC-d*8C_X(2|9r(K>tBV6KPXB5aR=akuHuvV&oae#Ny2~j0m^SW zK=~oXC-ZMN9RPpZ0q}P#K3V_!^Z@uT6rarh{iOJ0?UQ<~v7gi=`a4YV$@K42e6sdE z=>Yr(9RNT00Qg~wPiCJviccnAq2iPIuL};qf4bt6*TK?CVLzcS*wkCB-MR|F;f+|48x2C*j}uI@3M_li-IdzF!i2h2oRd|8m7A zTYufA_+eW>{UN#yGsHudu-!Jn%53zFb(Q~a-z;2-ngm&4KBjeq>chVw`K z--rLitMGawk4?*Zv^{Loz2P`b$X5F0ubO-<8gA3j`G-mOY3Swi3;c@)e$l`$8u zzi8kW4g8{kUo`NG27b}NFB-5Kc=&`--It}llX6!|&WZ1)?n!gUJ=tMThfh;y&N;;Q zhZNtcl;5S4{3kVd$sbcj`i{Ts$&>{fQ;N=hFeT&4=R0OEPhFDwhtxT9Zb(^@(vosR zito0R_tFpc9eU`Y%TkJ8Nx3HN%e35Z>dPIP(ud!W^8O*=lr1T*r+t_5eTS<%U)N>+ zT^;Z4Q2BW3mj_i-mV2>a=Wi25v2nuvq2~d2L&ToH?uP|GVSDcS42A7^>uQDVIqQhR z_I&j-3fptl?c^f7D^S>; z2WwQ=o&$SdVSCQ1D>e|B-=1e0rSQXfrv9}G+w)5+6}IP$UQ^hf2il{sJqL6mHqgo6 zp4XY8usx@9qr&!l&bJENb1VJfhnU}<+q+0%dtPsa!uFhADjwL9{?(~Q{(%bH^Lke( zY|rVvtgtyO7*f{+Z=I_W7&H;Q3 z+AwgBflCw~r*OH#lNFw?@N|W5B#cdW`ySk53fuSI-ci`TAGbqc`yN|5Hq@BkzTb76 z!dWdwo?M0Pdw~}zJYDfk3NKOkK805){8xqT`-ER8Y~KUxi5Hkye!n%QygY^N`-9UI zw(nalR@lBTxI*Dgnty}B_PwiC!gy%VW3A!uqAbEbg$ot#r|=wwvlYHa;SmbItZ<&f zKPVhf_$2Tq|8WY>PlEIt@H~b4Vw@xYg$kdk@DhdV6ke+E z9SSc~c%#D075-Y`l?wYXZj%2hg~uwqTH&h*<3H~WqtD+cT%hnn3I`Nkqj0gpA1XXf z;hhSvRJa>9sL6ko!h;lEt#FaTEecmEyh-630e3qFze}X>9~9oL@J9;sho0I0_&g*N zY4&%OFx&{dMd{%V1db}~1Kc46P7@dN55qt6+uvczB@6_ASDN@S_(vFj>@wK{U*Umo zG%!4dx$g16PkG?Y9{4j4j32ya`Eh>yEv`iPCxc;|5+Y*riY%t1)Esjtsea228I;o+T@}Cw}-w9 zEH_a;pMm4@{Mv&b>w(KW@MWI-OFj5|J@_>Sj?4S82mZlB|0_J8guIybn(G7u$K@Su z;5ffo29DcT$OGSH;EtBxqXv%id(FVOo9jIT$IJiHgHHh`$QP$S%mW{9;CTL#9=OCq zKgk1M=z&W;aFqwH^T2aG@B$Cq?167Ea9kfNJaCJFjce4f|=Bt>HWkcWSsB;VYnT>5XqZAl#;* zbDV*F8s=#@UBiVMF4wR{!)+S!hv>=Ar(vFk(=}YE;c^XIG~A{kzfB?eHO$j+x`qoi zT&`h@hTAlBj@SGe=4m)x!-X0y*RVyyZ5lc!XnqazG@Py>*ZGuhxrQwoZqtxI+V}r- zcP7D&TxA^ZBgYgcxaq(lAdn4FSx(zwC&WRvWWBXUem$vJ7d zn4FSx(x@{%*(5vUh#Zqsa!wj=VtTSkcE}MqCa2__6!$ORk@ZJ5$qqRp$K;fplg3+^ zo_q@S<|X7eB3~qD+0pG3cd@?Hj? zCnw~~q=Eb;{$a93o{?kn>*Rub4a$*pO|nm3kY6L`rpgOisutIV0!ff)vLxs$8;0*2yN>B0FSAj>rpgOisut zIV0!ff`oe?T|QYO>tvH`ksUH5N8|-LCMV>SoRM>KK^l0cQSB#dWSwl1EwV#~z zksUH5N8|-LCMV>SoRM>KL5hzmRX$lGn`DdZkRdrDFUT=DA*bYwoRbUEz}t(ITO;da zlWdV4G9*Xj1vw@srpgOisutIV0!ff)od3s(i9WHpv#*AwzORUXWvQLQcsU zIVTsSf%CH}m#mTXG#umeXY|7t4a4{{K;8@aF68@=A3%Nt`7z`tke@<+ z2KhPU7mzvRmyq8Kz>+=5^qW7Rlhy8ZKEK z%fIC$+Ep-u_N@EPrud+=6XoI;LE00pI0=t8;aL@)U6LApVSsw|2KMxNUUOJKfY%xArzH!BQ>dO*!-PR_ZW4 ztALzt@3cjA6Mmm1=1yQ+9(u96<-~U6s(PwklBi?RxHt4S;5#&FSw0*(BcSbAk=>UD zAiJ~}*NJz1?Svk6zuSHiUf$!-ve6;-x$Qao@F%NgmtpQd_Kr<+^Ug-QZN3hg;?h?< zRl=KTIWCGUj94+n5N<8?h_^7+O7YrZXDN8I567l9Jmg|dl_Iy)lrI#t1y|&#mKBxj zp#5(bYj)`wz8E7zv}gHn1dSP1C}wwn;8N(`P%V{>m0iHdE1Q(gk3wmB-j<5f&QnXl z2UdK)9N346=$3=s!HU*lL6$TRV<*~jde+cOFk1>0EP0PDDWr3YNw;qwysNdXCR1?$ z80Dsw-P=CcxSV>quEKrERrQiI5B*bE7gHRvD{~AZ z1=qM(_2{a`nNF=OjG$QmLGznXKfQp2flZ)Op|l-q%Og+AHqv@(lhNo zMhD;Gv0gq*@qC;Qf%owU&DU9p6Z>;GTDSXBj>=sJozN~@wzfX-9P476IKy9rGkdld z#L(|~L4euYQx3Y#p0f76)5w+0;@C;TP`dek&a!X#=gKc}A(*yKrU6nM9!O8+>;S{k zl{|p2Z~PA395@5`n>KXCkDO!IM_UrR&kzUQoc$ie$8ChQhv>mKn?3hz7*dllE5qU> za*{MgJC;7P;H=m%#kI4A?nQT_67qi!(-->o02zax0~;2f$9Cc!o$KBA)It|_&%G|< zhesw{f_LGW8ym5QN*OnvUg69c9=zQ|whiezv9k@meap_NKH;JHa;MnsHhOC3Qc-bV zJV|3ew1(Ir8?oc{RQNL$MRgt3wN=r&q}x{f_|Q$Nlul&`y1{XyN&%HR#qjRh0bEaS z1@`?)O_+66@v5BY_kB&Y6JbAh|;g-1ej0FT****=v0 z@W#{HpY(Ew^bA$`GbYoc%aG;PDivqw(a`UDPANb}D-&piA*OE_$o`v)V9k{wDn!Y| z%Vco^^MPF~6Vi3#(6i3z-a8ZFVuZ4vF*bi6({A!Ed!UaIVM%W0@q5n93fu#!NVj5)Nh<53#hD<`s#vy?lg?f1S=Ur|fo9 z$OqEq>JZxxFQqqx~$n)C4FtU|(+4T=ISxR%%3UcF?cJz)>$kzZ0Wx}rAc z?M@U7a^>Je&4P4=mJ_?t#Zm7VZEVCm^asP(J8y7WUplNWRcz382eNY5S(iB$>(o=$ zBCB=~NRt|;umiGhdr6}&W<>4FmlZ1J;|Gb`JKth`_j^0ojE9lKdE3T*F~nWRPa?Sq zMN1p9v{3ECl1|Q=tcWdGmXd~bipz#{_FeZ#FS3$~oKAw%12;*RVMzlcoF37|hF9dH z_Tvq8Vix>1sWND9CQCsbW8@`L<8ZAtzY0JX4ec4{S>#|jisOSLXm2Yc>Ua?Oq)R5g?vG=M~ zb<5bVvOrrN_N_}hQJ&*6NMd8TZVLK1onYw?vWwz@6L1yvF#XhWQfue|mowVscX5KH z5xiXPwXVKET!t(=ry@auQ|5ked1tyD>I!{qlFQ4sHoj|<*ug-KOss4p3DTdmsc2{S zyr>rAM(T9)fow!xae&*pr>+;CvSJ4^S66E0c2#wE#4bq#qh^IR;tw(}iYcx!Gp>>3 zf1Mk0jw)W#@)lLwHQ2qoI1jCyDBE_r^7w``J|9LfkyL$_#i=j78{vey{-tii z?>;FPk+NaPHD`cb_&W7SOJ0+mzC6j(hdz8%Ht)a8kNff3QA(S25L|COvcpjr2sx(Y zheFM+D;lu3w|$o27K$;&CDJ{@Gc2Z??wY40s3G=II;j!pXTsI|Pe;gNm zyeYW8O!ixwo4CE(PMDbLX8+bw$lK*k)5@I9arP_*Nv#;1KG*0sJ_fd7?CyKcb`;?y zFwhsJ+-uH?+bth$vd=BmTIpMjzB8>zdPT(2#uZ+eGNCRT7{zJURg|q((V%*_wd-aV$$4{14alt%IvPt zynIo)p1ytv!QoP#$Cl5DR}`S%WUiNa`bx9D+HvlAXT5&^RPkh%* z<`%AO>+2;0mDkb>`KEpqSsBIiUYs*DYz$KmV<%3RPWGx^%&)kD)x=q=l*kontya9e z;H*`}UXWgM*6L>NHEVVCT}fY})+(nN^S5uxd@p;o)KSH|i|iP(OUU_$*Ifz9@0yv2 zJr~QzKh{@&wQqyxPzSDbMqcL%bF*}-(OKkd_Uenn%~jV4`R%a&_a7MA BP>TQn literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/PkgInfo b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/PkgInfo new file mode 100644 index 00000000..bd04210f --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/SUStatus.nib b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/SUStatus.nib new file mode 100644 index 0000000000000000000000000000000000000000..356987eb973cec5c23bd2e40fecfe5732fe621ec GIT binary patch literal 6565 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 I{a-ooU;Q_Y@&Et; literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/Sparkle.icns b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/Sparkle.icns new file mode 100755 index 0000000000000000000000000000000000000000..8e56d45c0402ca41f1dc3993f8a79e93818d141c GIT binary patch literal 50219 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..ca40c5779c6680ea83c4d618b7538fea7c01d717 GIT binary patch literal 10477 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

  • >)*g?AwIPP4zUuh}>34EvUy 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 ABme*a literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..cabc211605a1a86066cf9ca29f25bd5bd6cd3362 GIT binary patch literal 9284 zcmeI2Yi}Dx6o$uN`4hMmQJ|tp4Bx0wlhUf7Qb3f8`i01e-PH0WmM<~RAI_hMfcKf> zli6LblQ?zas6v*#v%7OSb1v_ki~s#+J3I>2&98=&9Av%oDXby4Ek|uj>ixv|{gp`tpu7N9tD%V?A$%2WtJP`>{sTdm7tS z-L*nn@4Yt^4mGl_Hyu4~#a;Ot%-+$vv3ebb_j;cw?`g(Kc&go0!?*gD?~3^wnsuNr zl(f|IB(C3%v@v@x)GA$Ft6HHRPIWhk^#4_9iPJV_8qP&`MHR!(e^KOKd(EcTZxuYq?~^Acbyw)B-#vJ z^|%A%Ft20df^>(HV0Le9jqd2#L44i{XOS{?ZaUf2cq{=uIFfdu;b=QLhSj2Hr;#r| z>g`DTv%ZNpWfY*x^O}cd!96&C8rO#gq}dkN`l19{>$=t|eLcNgPgw)X)~B6@T>Kge z9ZD+)QR1LtNA!a)=w&tTbD|d3YPLU!GC*&T@`=7+LtWMg@5`l~a1yzkNLJ%GpUK4e zRn^SrqT^iBYsA)l;*ud|*`6QkgmHuh1KkRDqyAk7$BSo$Bl-1E`b-*Ss8`5+9!#e>n@!Kc^n5dz;L%u?1Zx= z;cvp=)t*E>JqdWN7Nc33PpUxZegy{pn@EuyZ;*Xo>ll7JieehET z(I0g0WlN)fiDwTUI6I&BLGYZ-=Q6+0{gIc#!>s23s+sn6 z4!acHm&i(U^-^OsJT!|{xVnG1teieh=`_RN(K3jVupP57mkroTjM$1;{~^-Z5n?4d zn1{#g`-%s#Z0zVv-%skXJMS#2guB(f@`-xD%@`;wSn)mH3GT=O6Hu8M(nI^M%jlJF{5E;v2H$WXx+7%fI{h^=Q#^MMK$2 ziSIRgmO6!(M{bNvzNc3geC&F5_oCGAUVd+uU#5xz+TC1oi;;$im#lp`;=Bx5%(1)m zaP$Z5Kl#Uo{`hCV%2wbG7)mUY?17vp(Y0k}->M%d>p1^RW4w+ukEE;2SLP|dxt>#f z;Sd(7o=C-@y+^gjJ&&r7>UHDDXrf$|P zLG@LxiZhNvAv4gMXz6&@j#AuP+z zB&!-?S6MV0#_H|cI4`|HE6bft)SgB^=IS}9CNOfGS-DtyOdck^v1zhyiLYrtWxi%M z^L$j22ek7N&o0XeYS(1>$X{@ZvNKvBlI3cCO`^DbBuq@g~E^%HG_Sv=?Iym#t5 zJJpq+KX2gEJv5!eYWyKeF1$U v>OtqQG_T;^w%m*}n~^JqGQ^wwPsaa4ah0A~ErkC_z*+1SiM9)NL3Q#!EPLer literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..83dbcbf38cc604a87aec1b2002aab730d07b7f80 GIT binary patch literal 7233 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 Muh)N5|K-pB2WhEJivR!s literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..939e0cb5ccc2f5b0f92f8bcfe656a3de6268cbec GIT binary patch literal 10624 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 OKJ+K)JNDl*^?v|2wv*2Q literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..8e2bf730f5b5c3d92a2a1395781b04c8644c6a54 GIT binary patch literal 12774 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..a453dfc16fabcca41a86012c8cb9deebee184c86 GIT binary patch literal 10244 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..9f85d65ccfb52a28fe3b80fed8e96fffc596798d GIT binary patch literal 12334 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 N@PCs3$NmmR{|^-JsLB8U literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..b741758fd1d16cc1e0513918e8509c89a195afa9 GIT binary patch literal 6908 zcmdT}-)kII6u!wr!KC#`C_Z&stXV?0n<|JR(nhUqNjux_q%0vd*q16eOS$p+)2O-MhDQXLi$8&4iYa-8*yd z+&TB0@0|0Uvul4RM6a-fEh_lT<8u;!t|*HduFr@n?s%dk3b_qMrmBv@ibRY%dv&4k{HLlUQPL?@MIP<6S!NFXVUNB?h}}+V^v<9 z#=I|i89O$_ew@Yzjd&1ex1;|XYwXfbuq^#y6cag0is&jKr4Q^7vmkM^%XrW$4`Ep1c4 zTnT%+5=+N0&#|dJg#cx1?$eJQ&frgX>mHDbQvCi!6*^8jlAgLLVmngkzkJKo1*TuFkAD zpCuV%p0YAYMwD5P`biXtm*-_{?d)4@MjNiXIJ|vu$6B-~37?8F#k4Omq#|Rqa#Y~w z)WdIJ@Z+M`tC`vBD3kg zJA=*xent-F*!!J`8Il<>+S4$%FdmV&FiTXBVfl2T9bO>{5ZGT-ukw@ncPgzB3A6YL~He}3U6`<;s z)=a7LEd7tWv8G_$)pcJL?_q4y?=~auj~_3&i9s@Kf8G+S?lose{gUM9jKEvh-blvM zi48)5JpTD|<;P>`7f;`k{`agE zlx`53R9ywus>D6fSZQLBT?tjIR^iv|W;Ad|BSOW;8s1I>5a;Y~a1Ar2M#Ss#j^7K> zvYRrulbD&4+T47J54O#P50dxm+?^Bcfj@{7}$_8}}Y!DA?l+TF=K6>nAb#!;q?>qLRk}hxI$FI-?Tv z%;oG3v#!y7JJlB=?^RJ(_1;?J?S5EgNbXDPs16|eehrMLWo&%#9+rG}8FHw8E^E+m z2hYs$s*7C@#Ci5+znnK$#nNO4tM2U!i>Ys#8Q`$J16|xvn;MU$*@^r4;z`GRDsKM- zmN1Z0&xHBF#-YQ^qLw&_?4#;hv(9EjC5MTwN8n4LV@a^x`BL&tJS)bA|;L*yotXx9hErX TX)VFu42X*`Q);(H<+y(Uj`#>3 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c4b9e9b9d045749304561684d7ccfb18f4acc334 GIT binary patch literal 6891 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ⅆU&>#`U%{{Duj1G6*YMZ! v*Yg|rjr{HWX8t~Y8^4|3%|FK<;@{yv9OVQdkl#jCAPy%Fk*$-G2cImPo(D+3| z3}B5INvkoTiSc5u41d8Z(-`%_z@1l(H(rzkO?qL{^?7EP&b+%&P7CKI2#Xo{Ywk~B6vep(j3)6Nesp>mGki-z?#^H@*Z9UP z_BkSl`IuI@{4$J{Nz5kXo%B0+`XttJ*cB1uST~ZV zaAHB6!EGGzCjNK7)%M7-p4!h|=-Kjr-TPs0ORlO^4Ef?GuFNkzoM{)wE6b6*FdCpm!Fpb};Gk6wdBhKO&5gWwjDLhx&T4BN5F)KB~ zecZ1xlEp81Q_3I4`6eVwWS9GmliwY^`*vZ8|f|=#O#~M}jrPr_B41Rh!zASnglhy4GWc3bT%BT6M{4)aEXQXZ! zEfgk{9vx^Z29(95{}Cy)#LSL`sL#CAC;e{}zogBLUbU}KCpv;`kND#E^WFVoY(2J+ zzmPdKR^5JdH&yXqH@RCy>!bL?D5o*oAyIsgC{-Q_b(}g_3}U3&9@+A5`fms85r33! z&iDJ`)ZS|{{#LgaLnKG6oSHuyJjb!TvPb+ zN{+L5hw_9D%$Y02-TRDQvLz`B4#w!2r2AU-dW4k%nzEAmG zwnuKIzUm`udU+c%4`UJY8gfV){A1#n%00M;H(~To;G6jm^Bv|NhDT|&lw_KWWH`+~ zZP?c*V;XZFm5r3M2-#AxF>@#58xNwJesaPOH|v%=crEa7iz*}=;eAjEVMADJWXhsMr=^ok{c(sKA7XOmWsOK z$GxSMG2YayI>N@mlj0BM`M9>c&it5zk0RQ#2Gw4&7mpTX^kD^|YMn|JRUAwYb4_ z`kGZ5s~BBTcUla=u{ZVO+dv&FVOGV4kv9E{Q%CVeM+7Wxb-$m8_D%*?!V&ZhGzM8a zGBdEfZ3bS(KO_b-660o@@*4ZFffaz3krYI#oT{r}jXa!|8dVJ!H?YfbpD+ zk^7(F$akk8hw28iLM`w9*$l3F;5k>!H}_$e_ip%)`Hg;?0~*kO+42`}b;j3%_F1zl z-vzox-FwS3g2O|D&7+Pu2kud|u3dXGlIrTxyK37=qGO1=7efwJ*{YiN#tSuaXm|3k z_7u~t({beSJxkNCvGagphl DG=<}@ literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Sparkle b/OSX/Sparkle.framework/Versions/A/Sparkle new file mode 100755 index 0000000000000000000000000000000000000000..64eefd02953848e3fae67c749445568d3220edff GIT binary patch literal 403600 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/Current b/OSX/Sparkle.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/OSX/Updater.h b/OSX/Updater.h new file mode 100644 index 00000000..05246f06 --- /dev/null +++ b/OSX/Updater.h @@ -0,0 +1,35 @@ +/* xscreensaver, Copyright (c) 2013 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 USE_IPHONE +#import +@interface XScreenSaverUpdater : NSObject +@end +#endif // !USE_IPHONE + +#define UPDATER_DOMAIN "org.jwz.xscreensaver.updater" + +// Strings must match Sparkle/SUConstants.m +#define SUSUEnableAutomaticChecksKey "SUEnableAutomaticChecks" +#define SUSUEnableAutomaticChecksDef YES +#define SUAutomaticallyUpdateKey "SUAutomaticallyUpdate" +#define SUAutomaticallyUpdateDef NO +#define SUSendProfileInfoKey "SUSendProfileInfo" +#define SUSendProfileInfoDef YES +#define SUScheduledCheckIntervalKey "SUScheduledCheckInterval" +#define SUScheduledCheckIntervalDef 604800 + +#define UPDATER_DEFAULTS @{ \ + @SUSUEnableAutomaticChecksKey: @SUSUEnableAutomaticChecksDef, \ + @SUAutomaticallyUpdateKey: @SUAutomaticallyUpdateDef, \ + @SUSendProfileInfoKey: @SUSendProfileInfoDef, \ + @SUScheduledCheckIntervalKey: @SUScheduledCheckIntervalDef \ +} diff --git a/OSX/Updater.m b/OSX/Updater.m new file mode 100644 index 00000000..2e3ccbe1 --- /dev/null +++ b/OSX/Updater.m @@ -0,0 +1,140 @@ +/* xscreensaver, Copyright (c) 2013 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. + * + * XScreenSaverUpdater.app -- downloads and installs XScreenSaver updates + * via Sparkle.framework. + * + * Created: 7-Dec-2013 + * + * NOTE: This does not work with Sparkle 1.5b6 -- it requires the "HEAD" + * version 4-Dec-2013 or later. + */ + +#import "Updater.h" +#import "Sparkle/SUUpdater.h" + +@implementation XScreenSaverUpdater : NSObject + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; + [defs registerDefaults:UPDATER_DEFAULTS]; + + SUUpdater *updater = [SUUpdater updaterForBundle: + [NSBundle bundleForClass:[self class]]]; + [updater setDelegate:self]; + + [self awaitScreenSaverTermination:updater]; +} + + +// Delegate method that lets us append extra info to the system-info URL. +// +- (NSArray *) feedParametersForUpdater:(SUUpdater *)updater + sendingSystemProfile:(BOOL)sending +{ + // Get the name of the saver that invoked us, and include that in the + // system info. + NSString *saver = [[[NSProcessInfo + processInfo]environment]objectForKey: + @"XSCREENSAVER_CLASSPATH"]; + if (! saver) return nil; + NSString *head = @"org.jwz.xscreensaver."; + if ([saver hasPrefix:head]) + saver = [saver substringFromIndex:[head length]]; + + return @[ @{ @"key": @"saver", + @"value": saver, + @"displayKey": @"Current Saver", + @"displayValue": saver + } + ]; +} + + +// Whether ScreenSaverEngine is currently running, meaning screen is blanked. +// +- (BOOL) screenSaverActive +{ + BOOL found = NO; + NSString *target = @"/ScreenSaverEngine.app"; + ProcessSerialNumber psn = { kNoProcess, kNoProcess }; + while (GetNextProcess(&psn) == noErr) { + CFDictionaryRef cfdict = + ProcessInformationCopyDictionary (&psn, + kProcessDictionaryIncludeAllInformationMask); + if (cfdict) { + NSDictionary *dict = (NSDictionary *) cfdict; + NSString *path = [dict objectForKey:@"BundlePath"]; + if (path && [path hasSuffix:target]) + found = YES; + CFRelease (cfdict); + } + if (found) + break; + } + return found; +} + + +// If the screen saver is not running, then launch the updater. +// Otherwise, wait a while and try again. This is because if the +// updater tries to pop up a dialog box while the screen saver is +// active, everything goes to hell and it never shows up. +// +- (void) awaitScreenSaverTermination:(SUUpdater *)updater +{ + if ([self screenSaverActive]) { + static float delay = 1; + [NSTimer scheduledTimerWithTimeInterval: delay + target:self + selector:@selector(awaitScreenSaverTerminationTimer:) + userInfo:updater + repeats:NO]; + // slightly exponential back-off + delay *= 1.3; + if (delay > 120) + delay = 120; + } else { + // Launch the updater thread. + [updater checkForUpdatesInBackground]; + + // Now we need to wait for the Sparkle thread to finish before we can + // exit, so just poll waiting for it. + // + [NSTimer scheduledTimerWithTimeInterval:1 + target:self + selector:@selector(exitWhenDone:) + userInfo:updater + repeats:YES]; + } +} + + +- (void) awaitScreenSaverTerminationTimer:(NSTimer *)timer +{ + [self awaitScreenSaverTermination:[timer userInfo]]; +} + + +- (void) exitWhenDone:(NSTimer *)timer +{ + SUUpdater *updater = [timer userInfo]; + if (![updater updateInProgress]) + [[NSApplication sharedApplication] terminate:self]; +} + + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app +{ + return YES; +} + +@end diff --git a/OSX/Updater.plist b/OSX/Updater.plist new file mode 100644 index 00000000..eb9a4504 --- /dev/null +++ b/OSX/Updater.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleGetInfoString + 5.26 + CFBundleIconFile + SaverRunner + CFBundleIdentifier + $(BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + 5.26 + CFBundleName + ${PRODUCT_NAME} + CFBundleDisplayName + XScreenSaver + CFBundlePackageType + APPL + CFBundleShortVersionString + 5.26 + CFBundleSignature + ???? + CFBundleVersion + 5.26 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + LSUIElement + + NSHumanReadableCopyright + 5.26 + NSMainNibFile + Updater + NSPrincipalClass + NSApplication + SUEnableSystemProfiling + + SUFeedURL + http://www.jwz.org/xscreensaver/updates.xml + SUPublicDSAKeyFile + sparkle_dsa_pub.pem + SUScheduledCheckInterval + 604800 + + diff --git a/OSX/Updater.xib b/OSX/Updater.xib new file mode 100644 index 00000000..03ebff78 --- /dev/null +++ b/OSX/Updater.xib @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OSX/XScreenSaver.icns b/OSX/XScreenSaver.icns new file mode 100644 index 0000000000000000000000000000000000000000..53579213e2b419085ddaff1eb47796f53cf3ce1b GIT binary patch literal 77001 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 A6#xJL literal 0 HcmV?d00001 diff --git a/OSX/XScreenSaver.plist b/OSX/XScreenSaver.plist new file mode 100644 index 00000000..a11f99aa --- /dev/null +++ b/OSX/XScreenSaver.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 5.26 + CFBundleSignature + ???? + CFBundleVersion + 5.26 + LSMinimumSystemVersion + 10.4 + NSMainNibFile + SaverRunner + NSPrincipalClass + XScreenSaver${EXECUTABLE_NAME}View + + diff --git a/OSX/XScreenSaverConfigSheet.h b/OSX/XScreenSaverConfigSheet.h new file mode 100644 index 00000000..b2fd4899 --- /dev/null +++ b/OSX/XScreenSaverConfigSheet.h @@ -0,0 +1,79 @@ +/* xscreensaver, Copyright (c) 2006-2013 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). + */ + +#ifdef USE_IPHONE +# import +# import +# define NSView UIView +# define NSUserDefaultsController NSUserDefaults +#else +# import +#endif + +#import "jwxyz.h" + +#import + +#undef USE_PICKER_VIEW + +@interface XScreenSaverConfigSheet : +# ifdef USE_IPHONE + UITableViewController +# else + NSWindow +# endif +{ + NSString *saver_name; + NSUserDefaultsController *userDefaultsController; + NSUserDefaultsController *globalDefaultsController; + NSDictionary *defaultOptions; + const XrmOptionDescRec *opts; + id xml_root, xml_parsing; + +# ifdef USE_IPHONE + UITextField *active_text_field; + NSMutableArray *controls; + NSMutableArray *pref_ctls; // UIControl objects, with index = c.tag + NSMutableArray *pref_keys; // ...and their corresponding resources +# ifdef USE_PICKER_VIEW + NSMutableArray *picker_values; +# endif +# endif + +} + +- (id)initWithXML: (NSData *) xml_data + options: (const XrmOptionDescRec *) opts + controller: (NSUserDefaultsController *) prefs + globalController: (NSUserDefaultsController *) globalPrefs + defaults: (NSDictionary *) defs; + +@end diff --git a/OSX/XScreenSaverConfigSheet.m b/OSX/XScreenSaverConfigSheet.m new file mode 100644 index 00000000..46b73dee --- /dev/null +++ b/OSX/XScreenSaverConfigSheet.m @@ -0,0 +1,3582 @@ +/* xscreensaver, Copyright (c) 2006-2013 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 "Updater.h" + +#import "jwxyz.h" +#import "InvertedSlider.h" + +#ifdef USE_IPHONE +# define NSView UIView +# define NSRect CGRect +# define NSSize CGSize +# define NSTextField UITextField +# define NSButton UIButton +# define NSFont UIFont +# define NSStepper UIStepper +# define NSMenuItem UIMenuItem +# define NSText UILabel +# define minValue minimumValue +# define maxValue maximumValue +# define setMinValue setMinimumValue +# define setMaxValue setMaximumValue +# define LABEL UILabel +#else +# define LABEL NSTextField +#endif // USE_IPHONE + +#undef LABEL_ABOVE_SLIDER +#define USE_HTML_LABELS + + +#pragma mark XML Parser + +/* I used to use the "NSXMLDocument" XML parser, but that doesn't exist + on iOS. The "NSXMLParser" parser exists on both OSX and iOS, so I + converted to use that. However, to avoid having to re-write all of + the old code, I faked out a halfassed implementation of the + "NSXMLNode" class that "NSXMLDocument" used to return. + */ + +#define NSXMLNode SimpleXMLNode +#define NSXMLElement SimpleXMLNode +#define NSXMLCommentKind SimpleXMLCommentKind +#define NSXMLElementKind SimpleXMLElementKind +#define NSXMLAttributeKind SimpleXMLAttributeKind +#define NSXMLTextKind SimpleXMLTextKind + +typedef enum { SimpleXMLCommentKind, + SimpleXMLElementKind, + SimpleXMLAttributeKind, + SimpleXMLTextKind, +} SimpleXMLKind; + +@interface SimpleXMLNode : NSObject +{ + SimpleXMLKind kind; + NSString *name; + SimpleXMLNode *parent; + NSMutableArray *children; + NSMutableArray *attributes; + id object; +} + +@property(nonatomic) SimpleXMLKind kind; +@property(nonatomic, retain) NSString *name; +@property(nonatomic, retain) SimpleXMLNode *parent; +@property(nonatomic, retain) NSMutableArray *children; +@property(nonatomic, retain) NSMutableArray *attributes; +@property(nonatomic, retain, getter=objectValue, setter=setObjectValue:) + id object; + +@end + +@implementation SimpleXMLNode + +@synthesize kind; +@synthesize name; +//@synthesize parent; +@synthesize children; +@synthesize attributes; +@synthesize object; + +- (id) init +{ + self = [super init]; + attributes = [NSMutableArray arrayWithCapacity:10]; + return self; +} + + +- (id) initWithName:(NSString *)n +{ + self = [self init]; + [self setKind:NSXMLElementKind]; + [self setName:n]; + return self; +} + + +- (void) setAttributesAsDictionary:(NSDictionary *)dict +{ + for (NSString *key in dict) { + NSObject *val = [dict objectForKey:key]; + SimpleXMLNode *n = [[SimpleXMLNode alloc] init]; + [n setKind:SimpleXMLAttributeKind]; + [n setName:key]; + [n setObjectValue:val]; + [attributes addObject:n]; + } +} + +- (SimpleXMLNode *) parent { return parent; } + +- (void) setParent:(SimpleXMLNode *)p +{ + NSAssert (!parent, @"parent already set"); + if (!p) return; + parent = p; + NSMutableArray *kids = [p children]; + if (!kids) { + kids = [NSMutableArray arrayWithCapacity:10]; + [p setChildren:kids]; + } + [kids addObject:self]; +} +@end + + +#pragma mark Implementing radio buttons + +/* The UIPickerView is a hideous and uncustomizable piece of shit. + I can't believe Apple actually released that thing on the world. + Let's fake up some radio buttons instead. + */ + +#if defined(USE_IPHONE) && !defined(USE_PICKER_VIEW) + +@interface RadioButton : UILabel +{ + int index; + NSArray *items; +} + +@property(nonatomic) int index; +@property(nonatomic, retain) NSArray *items; + +@end + +@implementation RadioButton + +@synthesize index; +@synthesize items; + +- (id) initWithIndex:(int)_index items:_items +{ + self = [super initWithFrame:CGRectZero]; + index = _index; + items = [_items retain]; + + [self setText: [[items objectAtIndex:index] objectAtIndex:0]]; + [self setBackgroundColor:[UIColor clearColor]]; + [self sizeToFit]; + + return self; +} + +@end + + +# endif // !USE_PICKER_VIEW + + +# pragma mark Implementing labels with clickable links + +#if defined(USE_IPHONE) && defined(USE_HTML_LABELS) + +@interface HTMLLabel : UIView +{ + NSString *html; + UIFont *font; + UIWebView *webView; +} + +@property(nonatomic, retain) NSString *html; +@property(nonatomic, retain) UIWebView *webView; + +- (id) initWithHTML:(NSString *)h font:(UIFont *)f; +- (id) initWithText:(NSString *)t font:(UIFont *)f; +- (void) setHTML:(NSString *)h; +- (void) setText:(NSString *)t; +- (void) sizeToFit; + +@end + +@implementation HTMLLabel + +@synthesize html; +@synthesize webView; + +- (id) initWithHTML:(NSString *)h font:(UIFont *)f +{ + self = [super init]; + if (! self) return 0; + font = [f retain]; + webView = [[UIWebView alloc] init]; + webView.delegate = self; + webView.dataDetectorTypes = UIDataDetectorTypeNone; + self. autoresizingMask = (UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight); + webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight); + [self addSubview: webView]; + [self setHTML: h]; + return self; +} + +- (id) initWithText:(NSString *)t font:(UIFont *)f +{ + self = [self initWithHTML:@"" font:f]; + if (! self) return 0; + [self setText: t]; + return self; +} + + +- (void) setHTML: (NSString *)h +{ + if (! h) return; + [h retain]; + if (html) [html release]; + html = h; + NSString *h2 = + [NSString stringWithFormat: + @"" + "" + "" +// "" + "" + "" + "" + "%@" + "" + "", + [font fontName], + [font pointSize], + [font lineHeight], + h]; + [webView loadHTMLString:h2 baseURL:[NSURL URLWithString:@""]]; +} + + +static char *anchorize (const char *url); + +- (void) setText: (NSString *)t +{ + t = [t stringByReplacingOccurrencesOfString:@"&" withString:@"&"]; + t = [t stringByReplacingOccurrencesOfString:@"<" withString:@"<"]; + t = [t stringByReplacingOccurrencesOfString:@">" withString:@">"]; + t = [t stringByReplacingOccurrencesOfString:@"\n\n" withString:@"

    "]; + t = [t stringByReplacingOccurrencesOfString:@"

    " + withString:@"

    " + withString:@"

    " + options:NSCaseInsensitiveSearch + range:NSMakeRange(0, [str length])]; + str = [str stringByReplacingOccurrencesOfString:@"
    " + withString:@"\n" + options:NSCaseInsensitiveSearch + range:NSMakeRange(0, [str length])]; + + for (NSString *s in [str componentsSeparatedByString: @"<"]) { + NSRange r = [s rangeOfString:@">"]; + if (r.length > 0) + s = [s substringFromIndex: r.location + r.length]; + result = [result stringByAppendingString: s]; + } + return result; +} + + +- (void) sizeToFit +{ + CGRect r = [self frame]; + + /* It would be sensible to just ask the UIWebView how tall the page is, + instead of hoping that NSString and UIWebView measure fonts and do + wrapping in exactly the same way, but I can't make that work. + Maybe because it loads async? + */ +# if 0 + r.size.height = [[webView + stringByEvaluatingJavaScriptFromString: + @"document.body.offsetHeight"] + doubleValue]; +# else + NSString *text = [self stripTags: html]; + CGSize s = r.size; + s.height = 999999; + s = [text sizeWithFont: font + constrainedToSize: s + lineBreakMode:NSLineBreakByWordWrapping]; + + // GAAAH. Add one more line, or the UIWebView is still scrollable! + // The text is sized right, but it lets you scroll it up anyway. + s.height += [font pointSize]; + + r.size.height = s.height; +# endif + + [self setFrame: r]; +} + + +- (void) dealloc +{ + [html release]; + [font release]; + [webView release]; + [super dealloc]; +} + +@end + +#endif // USE_IPHONE && USE_HTML_LABELS + + +@interface XScreenSaverConfigSheet (Private) + +- (void)traverseChildren:(NSXMLNode *)node on:(NSView *)parent; + +# ifndef USE_IPHONE +- (void) placeChild: (NSView *)c on:(NSView *)p right:(BOOL)r; +- (void) placeChild: (NSView *)c on:(NSView *)p; +static NSView *last_child (NSView *parent); +static void layout_group (NSView *group, BOOL horiz_p); +# else // USE_IPHONE +- (void) placeChild: (NSObject *)c on:(NSView *)p right:(BOOL)r; +- (void) placeChild: (NSObject *)c on:(NSView *)p; +- (void) placeSeparator; +- (void) bindResource:(NSObject *)ctl key:(NSString *)k reload:(BOOL)r; +- (void) refreshTableView; +# endif // USE_IPHONE + +@end + + +@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 + +# define FONT_SIZE 17 // Magic hardcoded UITableView font size. + +#pragma mark Talking to the resource database + + +/* Normally we read resources by looking up "KEY" in the database + "org.jwz.xscreensaver.SAVERNAME". But in the all-in-one iPhone + app, everything is stored in the database "org.jwz.xscreensaver" + instead, so transform keys to "SAVERNAME.KEY". + + NOTE: This is duplicated in PrefsReader.m, cause I suck. + */ +- (NSString *) makeKey:(NSString *)key +{ +# ifdef USE_IPHONE + NSString *prefix = [saver_name stringByAppendingString:@"."]; + if (! [key hasPrefix:prefix]) // Don't double up! + key = [prefix stringByAppendingString:key]; +# endif + return key; +} + + +- (NSString *) makeCKey:(const char *)key +{ + return [self makeKey:[NSString stringWithCString:key + encoding:NSUTF8StringEncoding]]; +} + + +/* Given a command-line option, returns the corresponding resource name. + Any arguments in the switch string are ignored (e.g., "-foo x"). + */ +- (NSString *) switchToResource:(NSString *)cmdline_switch + opts:(const XrmOptionDescRec *)opts_array + valRet:(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 %@", cmdline_switch); + return 0; + } + char *s = strpbrk(buf, " \t\r\n"); + if (s && *s) { + *s = 0; + tail = s+1; + while (*tail && (*tail == ' ' || *tail == '\t')) + tail++; + } + + while (opts_array[0].option) { + if (!strcmp (opts_array[0].option, buf)) { + const char *ret = 0; + + if (opts_array[0].argKind == XrmoptionNoArg) { + if (tail && *tail) + NSAssert1 (0, @"expected no args to switch: \"%@\"", + cmdline_switch); + ret = opts_array[0].value; + } else { + if (!tail || !*tail) + NSAssert1 (0, @"expected args to switch: \"%@\"", + cmdline_switch); + ret = tail; + } + + if (val_ret) + *val_ret = (ret + ? [NSString stringWithCString:ret + encoding:NSUTF8StringEncoding] + : 0); + + const char *res = opts_array[0].specifier; + while (*res && (*res == '.' || *res == '*')) + res++; + return [self makeCKey:res]; + } + opts_array++; + } + + NSAssert1 (0, @"\"%@\" not present in options", cmdline_switch); + return 0; +} + + +- (NSUserDefaultsController *)controllerForKey:(NSString *)key +{ + static NSDictionary *a = 0; + if (! a) { + a = UPDATER_DEFAULTS; + [a retain]; + } + if ([a objectForKey:key]) + // These preferences are global to all xscreensavers. + return globalDefaultsController; + else + // All other preferences are per-saver. + return userDefaultsController; +} + + +#ifdef USE_IPHONE + +// Called when a slider is bonked. +// +- (void)sliderAction:(UISlider*)sender +{ + if ([active_text_field canResignFirstResponder]) + [active_text_field resignFirstResponder]; + NSString *pref_key = [pref_keys objectAtIndex: [sender tag]]; + + // Hacky API. See comment in InvertedSlider.m. + double v = ([sender isKindOfClass: [InvertedSlider class]] + ? [(InvertedSlider *) sender transformedValue] + : [sender value]); + + [[self controllerForKey:pref_key] + setObject:((v == (int) v) + ? [NSNumber numberWithInt:(int) v] + : [NSNumber numberWithDouble: v]) + forKey:pref_key]; +} + +// Called when a checkbox/switch is bonked. +// +- (void)switchAction:(UISwitch*)sender +{ + if ([active_text_field canResignFirstResponder]) + [active_text_field resignFirstResponder]; + NSString *pref_key = [pref_keys objectAtIndex: [sender tag]]; + NSString *v = ([sender isOn] ? @"true" : @"false"); + [[self controllerForKey:pref_key] setObject:v forKey:pref_key]; +} + +# ifdef USE_PICKER_VIEW +// Called when a picker is bonked. +// +- (void)pickerView:(UIPickerView *)pv + didSelectRow:(NSInteger)row + inComponent:(NSInteger)column +{ + if ([active_text_field canResignFirstResponder]) + [active_text_field resignFirstResponder]; + + NSAssert (column == 0, @"internal error"); + NSArray *a = [picker_values objectAtIndex: [pv tag]]; + if (! a) return; // Too early? + a = [a objectAtIndex:row]; + NSAssert (a, @"missing row"); + +//NSString *label = [a objectAtIndex:0]; + NSString *pref_key = [a objectAtIndex:1]; + NSObject *pref_val = [a objectAtIndex:2]; + [[self controllerForKey:pref_key] setObject:pref_val forKey:pref_key]; +} +# else // !USE_PICKER_VIEW + +// Called when a RadioButton is bonked. +// +- (void)radioAction:(RadioButton*)sender +{ + if ([active_text_field canResignFirstResponder]) + [active_text_field resignFirstResponder]; + + NSArray *item = [[sender items] objectAtIndex: [sender index]]; + NSString *pref_key = [item objectAtIndex:1]; + NSObject *pref_val = [item objectAtIndex:2]; + [[self controllerForKey:pref_key] setObject:pref_val forKey:pref_key]; +} + +- (BOOL)textFieldShouldBeginEditing:(UITextField *)tf +{ + active_text_field = tf; + return YES; +} + +- (void)textFieldDidEndEditing:(UITextField *)tf +{ + NSString *pref_key = [pref_keys objectAtIndex: [tf tag]]; + NSString *txt = [tf text]; + [[self controllerForKey:pref_key] setObject:txt forKey:pref_key]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)tf +{ + active_text_field = nil; + [tf resignFirstResponder]; + return YES; +} + +# endif // !USE_PICKER_VIEW + +#endif // USE_IPHONE + + +# ifndef USE_IPHONE + +- (void) okAction:(NSObject *)arg +{ + [userDefaultsController commitEditing]; + [globalDefaultsController commitEditing]; + [userDefaultsController save:self]; + [globalDefaultsController save:self]; + [NSApp endSheet:self returnCode:NSOKButton]; + [self close]; +} + +- (void) cancelAction:(NSObject *)arg +{ + [userDefaultsController revert:self]; + [globalDefaultsController revert:self]; + [NSApp endSheet:self returnCode:NSCancelButton]; + [self close]; +} +# endif // !USE_IPHONE + + +- (void) resetAction:(NSObject *)arg +{ +# ifndef USE_IPHONE + [userDefaultsController revertToInitialValues:self]; + [globalDefaultsController revertToInitialValues:self]; +# else // USE_IPHONE + + for (NSString *key in defaultOptions) { + NSObject *val = [defaultOptions objectForKey:key]; + [[self controllerForKey:key] setObject:val forKey:key]; + } + + for (UIControl *ctl in pref_ctls) { + NSString *pref_key = [pref_keys objectAtIndex: ctl.tag]; + [self bindResource:ctl key:pref_key reload:YES]; + } + + [self refreshTableView]; +# endif // USE_IPHONE +} + + +/* Connects a control (checkbox, etc) to the corresponding preferences key. + */ +- (void) bindResource:(NSObject *)control key:(NSString *)pref_key + reload:(BOOL)reload_p +{ + NSUserDefaultsController *prefs = [self controllerForKey:pref_key]; +# ifndef USE_IPHONE + 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]; +# else // USE_IPHONE + SEL sel; + NSObject *val = [prefs objectForKey:pref_key]; + NSString *sval = 0; + double dval = 0; + + if ([val isKindOfClass:[NSString class]]) { + sval = (NSString *) val; + if (NSOrderedSame == [sval caseInsensitiveCompare:@"true"] || + NSOrderedSame == [sval caseInsensitiveCompare:@"yes"] || + NSOrderedSame == [sval caseInsensitiveCompare:@"1"]) + dval = 1; + else + dval = [sval doubleValue]; + } else if ([val isKindOfClass:[NSNumber class]]) { + // NSBoolean (__NSCFBoolean) is really NSNumber. + dval = [(NSNumber *) val doubleValue]; + sval = [(NSNumber *) val stringValue]; + } + + if ([control isKindOfClass:[UISlider class]]) { + sel = @selector(sliderAction:); + // Hacky API. See comment in InvertedSlider.m. + if ([control isKindOfClass:[InvertedSlider class]]) + [(InvertedSlider *) control setTransformedValue: dval]; + else + [(UISlider *) control setValue: dval]; + } else if ([control isKindOfClass:[UISwitch class]]) { + sel = @selector(switchAction:); + [(UISwitch *) control setOn: ((int) dval != 0)]; +# ifdef USE_PICKER_VIEW + } else if ([control isKindOfClass:[UIPickerView class]]) { + sel = 0; + [(UIPickerView *) control selectRow:((int)dval) inComponent:0 + animated:NO]; +# else // !USE_PICKER_VIEW + } else if ([control isKindOfClass:[RadioButton class]]) { + sel = 0; // radioAction: sent from didSelectRowAtIndexPath. + } else if ([control isKindOfClass:[UITextField class]]) { + sel = 0; // #### + [(UITextField *) control setText: sval]; +# endif // !USE_PICKER_VIEW + } else { + NSAssert (0, @"unknown class"); + } + + // NSLog(@"\"%@\" = \"%@\" [%@, %.1f]", pref_key, val, [val class], dval); + + if (!reload_p) { + if (! pref_keys) { + pref_keys = [[NSMutableArray arrayWithCapacity:10] retain]; + pref_ctls = [[NSMutableArray arrayWithCapacity:10] retain]; + } + + [pref_keys addObject: [self makeKey:pref_key]]; + [pref_ctls addObject: control]; + ((UIControl *) control).tag = [pref_keys count] - 1; + + if (sel) { + [(UIControl *) control addTarget:self action:sel + forControlEvents:UIControlEventValueChanged]; + } + } + +# endif // USE_IPHONE + +# 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 (@"%@ %@/%@", s, [def class], [control class]); +# endif +} + + +- (void) bindResource:(NSObject *)control key:(NSString *)pref_key +{ + [self bindResource:(NSObject *)control key:(NSString *)pref_key reload:NO]; +} + + + +- (void) bindSwitch:(NSObject *)control + cmdline:(NSString *)cmd +{ + [self bindResource:control + key:[self switchToResource:cmd opts:opts valRet:0]]; +} + + +#pragma mark Text-manipulating utilities + + +static NSString * +unwrap (NSString *text) +{ + // Unwrap lines: delete \n but do not delete \n\n. + // + NSArray *lines = [text componentsSeparatedByString:@"\n"]; + int nlines = [lines count]; + BOOL eolp = YES; + int i; + + text = @"\n"; // start with one blank line + + // skip trailing blank lines in file + for (i = nlines-1; i > 0; i--) { + NSString *s = (NSString *) [lines objectAtIndex:i]; + if ([s length] > 0) + break; + nlines--; + } + + // skip leading blank lines in file + for (i = 0; i < nlines; i++) { + NSString *s = (NSString *) [lines objectAtIndex:i]; + if ([s length] > 0) + break; + } + + // unwrap + Bool any = NO; + for (; i < nlines; i++) { + NSString *s = (NSString *) [lines objectAtIndex:i]; + if ([s length] == 0) { + text = [text stringByAppendingString:@"\n\n"]; + eolp = YES; + } else if ([s characterAtIndex:0] == ' ' || + [s hasPrefix:@"Copyright "] || + [s hasPrefix:@"http://"]) { + // don't unwrap if the following line begins with whitespace, + // or with the word "Copyright", or if it begins with a URL. + if (any && !eolp) + text = [text stringByAppendingString:@"\n"]; + text = [text stringByAppendingString:s]; + any = YES; + eolp = NO; + } else { + if (!eolp) + text = [text stringByAppendingString:@" "]; + text = [text stringByAppendingString:s]; + eolp = NO; + any = YES; + } + } + + return text; +} + + +# ifndef USE_IPHONE +/* Makes the text up to the first comma be bold. + */ +static void +boldify (NSText *nstext) +{ + NSString *text = [nstext string]; + NSRange r = [text rangeOfString:@"," options:0]; + r.length = r.location+1; + + r.location = 0; + + NSFont *font = [nstext font]; + font = [NSFont boldSystemFontOfSize:[font pointSize]]; + [nstext setFont:font range:r]; +} +# endif // !USE_IPHONE + + +/* Creates a human-readable anchor to put on a URL. + */ +static char * +anchorize (const char *url) +{ + const char *wiki = "http://en.wikipedia.org/wiki/"; + const char *math = "http://mathworld.wolfram.com/"; + if (!strncmp (wiki, url, strlen(wiki))) { + char *anchor = (char *) malloc (strlen(url) * 3 + 10); + strcpy (anchor, "Wikipedia: \""); + const char *in = url + strlen(wiki); + char *out = anchor + strlen(anchor); + while (*in) { + if (*in == '_') { + *out++ = ' '; + } else if (*in == '#') { + *out++ = ':'; + *out++ = ' '; + } else if (*in == '%') { + char hex[3]; + hex[0] = in[1]; + hex[1] = in[2]; + hex[2] = 0; + int n = 0; + sscanf (hex, "%x", &n); + *out++ = (char) n; + in += 2; + } else { + *out++ = *in; + } + in++; + } + *out++ = '"'; + *out = 0; + return anchor; + + } else if (!strncmp (math, url, strlen(math))) { + char *anchor = (char *) malloc (strlen(url) * 3 + 10); + strcpy (anchor, "MathWorld: \""); + const char *start = url + strlen(wiki); + const char *in = start; + char *out = anchor + strlen(anchor); + while (*in) { + if (*in == '_') { + *out++ = ' '; + } else if (in != start && *in >= 'A' && *in <= 'Z') { + *out++ = ' '; + *out++ = *in; + } else if (!strncmp (in, ".htm", 4)) { + break; + } else { + *out++ = *in; + } + in++; + } + *out++ = '"'; + *out = 0; + return anchor; + + } else { + return strdup (url); + } +} + + +#if !defined(USE_IPHONE) || !defined(USE_HTML_LABELS) + +/* Converts any http: URLs in the given text field to clickable links. + */ +static void +hreffify (NSText *nstext) +{ +# ifndef USE_IPHONE + NSString *text = [nstext string]; + [nstext setRichText:YES]; +# else + NSString *text = [nstext text]; +# endif + + int L = [text length]; + NSRange start; // range is start-of-search to end-of-string + start.location = 0; + start.length = L; + while (start.location < L) { + + // Find the beginning of a URL... + // + NSRange r2 = [text rangeOfString:@"http://" options:0 range:start]; + if (r2.location == NSNotFound) + break; + + // Next time around, start searching after this. + start.location = r2.location + r2.length; + start.length = L - start.location; + + // Find the end of a URL (whitespace or EOF)... + // + NSRange r3 = [text rangeOfCharacterFromSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet] + options:0 range:start]; + if (r3.location == NSNotFound) // EOF + r3.location = L, r3.length = 0; + + // Next time around, start searching after this. + start.location = r3.location; + start.length = L - start.location; + + // Set r2 to the start/length of this URL. + r2.length = start.location - r2.location; + + // Extract the URL. + NSString *nsurl = [text substringWithRange:r2]; + const char *url = [nsurl UTF8String]; + + // If this is a Wikipedia URL, make the linked text be prettier. + // + char *anchor = anchorize(url); + +# ifndef USE_IPHONE + + // Construct the RTF corresponding to anchor + // + const char *fmt = "{\\field{\\*\\fldinst{HYPERLINK \"%s\"}}%s}"; + char *rtf = malloc (strlen (fmt) + strlen(url) + strlen(anchor) + 10); + sprintf (rtf, fmt, url, anchor); + + NSData *rtfdata = [NSData dataWithBytesNoCopy:rtf length:strlen(rtf)]; + [nstext replaceCharactersInRange:r2 withRTF:rtfdata]; + +# else // !USE_IPHONE + // *anchor = 0; // Omit Wikipedia anchor + text = [text stringByReplacingCharactersInRange:r2 + withString:[NSString stringWithCString:anchor + encoding:NSUTF8StringEncoding]]; + // text = [text stringByReplacingOccurrencesOfString:@"\n\n\n" + // withString:@"\n\n"]; +# endif // !USE_IPHONE + + free (anchor); + + int L2 = [text length]; // might have changed + start.location -= (L - L2); + L = L2; + } + +# ifdef USE_IPHONE + [nstext setText:text]; + [nstext sizeToFit]; +# endif +} + +#endif /* !USE_IPHONE || !USE_HTML_LABELS */ + + + +#pragma mark Creating controls from XML + + +/* 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. + */ +- (void) parseAttrs:(NSMutableDictionary *)dict node:(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 \"%@\"", key, [node name]); + } else if ([old length] != 0) { + NSAssert3 (0, @"duplicate %@: \"%@\", \"%@\"", key, 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]; + } + +# ifdef USE_IPHONE + // Kludge for starwars.xml: + // If there is a "_low-label" and no "_label", but "_low-label" contains + // spaces, divide them. + NSString *lab = [dict objectForKey:@"_label"]; + NSString *low = [dict objectForKey:@"_low-label"]; + if (low && !lab) { + NSArray *split = + [[[low stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]] + componentsSeparatedByString: @" "] + filteredArrayUsingPredicate: + [NSPredicate predicateWithFormat:@"length > 0"]]; + if (split && [split count] == 2) { + [dict setValue:[split objectAtIndex:0] forKey:@"_label"]; + [dict setValue:[split objectAtIndex:1] forKey:@"_low-label"]; + } + } +# endif // USE_IPHONE +} + + +/* Handle the options on the top level tag. + */ +- (NSString *) parseXScreenSaverTag:(NSXMLNode *)node +{ + NSMutableDictionary *dict = [@{ @"name": @"", + @"_label": @"", + @"gl": @"" } + mutableCopy]; + [self parseAttrs:dict node:node]; + NSString *name = [dict objectForKey:@"name"]; + NSString *label = [dict objectForKey:@"_label"]; + + NSAssert1 (label, @"no _label in %@", [node name]); + NSAssert1 (name, @"no name in \"%@\"", label); + return label; +} + + +/* Creates a label: an un-editable NSTextField displaying the given text. + */ +- (LABEL *) makeLabel:(NSString *)text +{ + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; +# ifndef USE_IPHONE + NSTextField *lab = [[NSTextField alloc] initWithFrame:rect]; + [lab setSelectable:NO]; + [lab setEditable:NO]; + [lab setBezeled:NO]; + [lab setDrawsBackground:NO]; + [lab setStringValue:text]; + [lab sizeToFit]; +# else // USE_IPHONE + UILabel *lab = [[UILabel alloc] initWithFrame:rect]; + [lab setText: [text stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]]]; + [lab setBackgroundColor:[UIColor clearColor]]; + [lab setNumberOfLines:0]; // unlimited + // [lab setLineBreakMode:UILineBreakModeWordWrap]; + [lab setLineBreakMode:NSLineBreakByTruncatingHead]; + [lab setAutoresizingMask: (UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight)]; +# endif // USE_IPHONE + return lab; +} + + +/* Creates the checkbox (NSButton) described by the given XML node. + */ +- (void) makeCheckbox:(NSXMLNode *)node on:(NSView *)parent +{ + NSMutableDictionary *dict = [@{ @"id": @"", + @"_label": @"", + @"arg-set": @"", + @"arg-unset": @"" } + mutableCopy]; + [self parseAttrs:dict node: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 %@", [node name]); + return; + } + if (!arg_set && !arg_unset) { + NSAssert1 (0, @"neither arg-set nor arg-unset provided in \"%@\"", + label); + } + if (arg_set && arg_unset) { + NSAssert1 (0, @"only one of arg-set and arg-unset may be used in \"%@\"", + 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 \"%@\": %@", + label, arg_set); + if (arg_unset && (![arg_unset hasPrefix:@"-no-"] && + ![arg_unset hasPrefix:@"--no-"])) + NSLog(@"arg-unset should be a \"no\" option in \"%@\": %@", + label, arg_unset); + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = rect.size.height = 10; + +# ifndef USE_IPHONE + + NSButton *button = [[NSButton alloc] initWithFrame:rect]; + [button setButtonType:NSSwitchButton]; + [button setTitle:label]; + [button sizeToFit]; + [self placeChild:button on:parent]; + +# else // USE_IPHONE + + LABEL *lab = [self makeLabel:label]; + [self placeChild:lab on:parent]; + UISwitch *button = [[UISwitch alloc] initWithFrame:rect]; + [self placeChild:button on:parent right:YES]; + [lab release]; + +# endif // USE_IPHONE + + [self bindSwitch:button cmdline:(arg_set ? arg_set : arg_unset)]; + [button release]; +} + + +/* 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. + */ +- (void) makeNumberSelector:(NSXMLNode *)node on:(NSView *)parent +{ + NSMutableDictionary *dict = [@{ @"id": @"", + @"_label": @"", + @"_low-label": @"", + @"_high-label": @"", + @"type": @"", + @"arg": @"", + @"low": @"", + @"high": @"", + @"default": @"", + @"convert": @"" } + mutableCopy]; + [self parseAttrs:dict node: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 %@", label); + NSAssert1 (type, @"no type in %@", label); + + if (! low) { + NSAssert1 (0, @"no low in %@", [node name]); + return; + } + if (! high) { + NSAssert1 (0, @"no high in %@", [node name]); + return; + } + if (! def) { + NSAssert1 (0, @"no default in %@", [node name]); + return; + } + if (cvt && ![cvt isEqualToString:@"invert"]) { + NSAssert1 (0, @"if provided, \"convert\" must be \"invert\" in %@", + label); + } + + // If either the min or max field contains a decimal point, then this + // option may have a floating point value; otherwise, it is constrained + // to be an integer. + // + NSCharacterSet *dot = + [NSCharacterSet characterSetWithCharactersInString:@"."]; + BOOL float_p = ([low rangeOfCharacterFromSet:dot].location != NSNotFound || + [high rangeOfCharacterFromSet:dot].location != NSNotFound); + + if ([type isEqualToString:@"slider"] +# ifdef USE_IPHONE // On iPhone, we use sliders for all numeric values. + || [type isEqualToString:@"spinbutton"] +# endif + ) { + + NSRect rect; + rect.origin.x = rect.origin.y = 0; + rect.size.width = 150; + rect.size.height = 23; // apparent min height for slider with ticks... + NSSlider *slider; + slider = [[InvertedSlider alloc] initWithFrame:rect + inverted: !!cvt + integers: !float_p]; + [slider setMaxValue:[high doubleValue]]; + [slider setMinValue:[low doubleValue]]; + + int range = [slider maxValue] - [slider minValue] + 1; + int range2 = range; + int max_ticks = 21; + while (range2 > max_ticks) + range2 /= 10; + + // If we have elided ticks, leave it at the max number of ticks. + if (range != range2 && range2 < max_ticks) + range2 = max_ticks; + + // If it's a float, always display the max number of ticks. + if (float_p && range2 < max_ticks) + range2 = max_ticks; + +# ifndef USE_IPHONE + [slider setNumberOfTickMarks:range2]; + + [slider setAllowsTickMarkValuesOnly: + (range == range2 && // we are showing the actual number of ticks + !float_p)]; // and we want integer results +# endif // !USE_IPHONE + + // #### Note: when the slider's range is large enough that we aren't + // showing all possible ticks, the slider's value is not constrained + // to be an integer, even though it should be... + // Maybe we need to use a value converter or something? + + LABEL *lab; + if (label) { + lab = [self makeLabel:label]; + [self placeChild:lab on:parent]; +# ifdef USE_IPHONE + if (low_label) { + CGFloat s = [NSFont systemFontSize] + 4; + [lab setFont:[NSFont boldSystemFontOfSize:s]]; + } +# endif + [lab release]; + } + + if (low_label) { + lab = [self makeLabel:low_label]; + [lab setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; +# ifndef USE_IPHONE + [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]; + [self placeChild:lab on:parent]; +# else // USE_IPHONE + [lab setTextAlignment: NSTextAlignmentRight]; + [self placeChild:lab on:parent right:(label ? YES : NO)]; +# endif // USE_IPHONE + + [lab release]; + } + +# ifndef USE_IPHONE + [self placeChild:slider on:parent right:(low_label ? YES : NO)]; +# else // USE_IPHONE + [self placeChild:slider on:parent right:(label || low_label ? YES : NO)]; +# endif // USE_IPHONE + + if (low_label) { + // Make left label be same height as slider. + rect = [lab frame]; + rect.size.height = [slider frame].size.height; + [lab setFrame:rect]; + } + + 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) { + lab = [self makeLabel:high_label]; + [lab setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + rect = [lab frame]; + + // Make right label be same height as slider. + rect.size.height = [slider frame].size.height; + [lab setFrame:rect]; + [self placeChild:lab on:parent right:YES]; + [lab release]; + } + + [self bindSwitch:slider cmdline:arg]; + [slider release]; + +#ifndef USE_IPHONE // On iPhone, we use sliders for all numeric values. + + } else if ([type isEqualToString:@"spinbutton"]) { + + if (! label) { + NSAssert1 (0, @"no _label in spinbutton %@", [node name]); + return; + } + NSAssert1 (!low_label, + @"low-label not allowed in spinbutton \"%@\"", [node name]); + NSAssert1 (!high_label, + @"high-label not allowed in spinbutton \"%@\"", [node name]); + NSAssert1 (!cvt, @"convert not allowed in spinbutton \"%@\"", + [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) { + LABEL *lab = [self makeLabel: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]; + [self placeChild:lab on:parent]; + [lab release]; + } + + [self placeChild:txt on:parent right:(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]; + [self placeChild:step on:parent right:YES]; + rect = [step frame]; + rect.origin.x -= COLUMN_SPACING; // this one goes close + rect.origin.y += ([txt frame].size.height - rect.size.height) / 2; + [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]; + + NSNumberFormatter *fmt = [[[NSNumberFormatter alloc] init] autorelease]; + [fmt setFormatterBehavior:NSNumberFormatterBehavior10_4]; + [fmt setNumberStyle:NSNumberFormatterDecimalStyle]; + [fmt setMinimum:[NSNumber numberWithDouble:[low doubleValue]]]; + [fmt setMaximum:[NSNumber numberWithDouble:[high doubleValue]]]; + [fmt setMinimumFractionDigits: (float_p ? 1 : 0)]; + [fmt setMaximumFractionDigits: (float_p ? 2 : 0)]; + + [fmt setGeneratesDecimalNumbers:float_p]; + [[txt cell] setFormatter:fmt]; + + [self bindSwitch:step cmdline:arg]; + [self bindSwitch:txt cmdline:arg]; + + [step release]; + [txt release]; + +# endif // USE_IPHONE + + } else { + NSAssert2 (0, @"unknown type \"%@\" in \"%@\"", type, label); + } +} + + +# ifndef USE_IPHONE +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]); +} +# endif // !USE_IPHONE + + +/* Creates the popup menu described by the given XML node (and its children). + */ +- (void) makeOptionMenu:(NSXMLNode *)node on:(NSView *)parent +{ + NSArray *children = [node children]; + int i, count = [children count]; + + if (count <= 0) { + NSAssert1 (0, @"no menu items in \"%@\"", [node name]); + return; + } + + // get the "id" attribute off the + //

    + + +
    + */ + + //
    + + NSRect rect; + rect.size.width = rect.size.height = 1; + rect.origin.x = rect.origin.y = 0; + NSView *group = [[NSView alloc] initWithFrame:rect]; + + NSXMLElement *node2; + + // + + node2 = [[NSXMLElement alloc] initWithName:@"boolean"]; + [node2 setAttributesAsDictionary: + @{ @"id": @SUSUEnableAutomaticChecksKey, + @"_label": @"Automatically check for updates", + @"arg-unset": @"-no-" SUSUEnableAutomaticChecksKey, + }]; + [self makeCheckbox:node2 on:group]; + + // + +
    + + <_description> +A fully-functional VT100 terminal emulator simulating an old terminal, +with large pixels and long-sustain phosphor. + +Written by Jamie Zawinski; 1999. + + diff --git a/OSX/sign_update.rb b/OSX/sign_update.rb new file mode 100755 index 00000000..6d03e2ef --- /dev/null +++ b/OSX/sign_update.rb @@ -0,0 +1,7 @@ +#!/usr/bin/ruby +if ARGV.length < 2 + puts "Usage: ruby sign_update.rb update_archive private_key" + exit +end + +puts `openssl dgst -sha1 -binary < "#{ARGV[0]}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64` \ No newline at end of file diff --git a/OSX/sparkle_dsa_pub.pem b/OSX/sparkle_dsa_pub.pem new file mode 100644 index 00000000..f8a9229e --- /dev/null +++ b/OSX/sparkle_dsa_pub.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDOzCCAi4GByqGSM44BAEwggIhAoIBAQDekjUm7Fk/mm887ldKk4qfLq1lb3Wg +Num4oLRJBJlGcKzKKA0jP4J9BgXZvuOs3FEzpwPK+P6LajWkBhG2kaxNSwwOlQjp +dAqeMeV8EZxKiu5+msudl6QHOuIk+fwpDlB007KPI+JAxnrrmkI7nlLDv2EBVAJw +78rSlcI6co3AiXHEe5H2J0LsZe6pi3U4FeCJXu7vr1+yNn5Gw8MX9hXl1EjOkN9e +gCbDEZrX2UPSUWpiIfZwpjAXnit2MV045niww6/jz5nz58Y/ZMbuLQW205B2gzPB +XUVH50tMhbKPnU51aRyWcDWVIYMeqryjKqsy/IjDZC5zwdUbDA66ZwuXAhUAywjB +FIUjBpzyPldDNeVwq/uG9eECggEBAMMDXX0R6Hib2MR3icbJVsIEPZ9EUli6e8F6 +htypUNNTwaNbkz0v74ruyrJ9cPtWGFgU5gCS5uTKmeIA15i+clxGFy6kqWyAxrAT +h0ehuo572Htdayh9Z7N3UGVpNG+ryYfaxWhYl0sgd/vvsptZpBbmQe+F1/BR9/C0 +J3J4CsAv3Ut0dzWjap4dGefSMYXUX+BikfsLaSeqSR07r5jvNsT2L4av1RnZagSl +zzq3Tx6fepfgPHdf1A5/cnbzNz+Uf98YxlYXylqpbGBL1wmhseiHNxJCKSsCrHz1 +UWJqj31WHD6trQoGN9/1y74w0Y9sveHK8RApEoKitTTcL3Dn/ZYDggEFAAKCAQAU +ofRd/dLgvCmA9gzyagc1TSYGoIjuNOpagqs6KpzhPAH+dA6/zlWy+iA/5rA6tm5Y +JOOrmTudXcBu9Y2NJDJIzD0WphkigUs0YTml257X7+74DSuIWH1d70hhPwhkuMeM +6AjnEHGcmlXRPbeMT0+ALlBW8GEmJBagazSXUXRXkyj+902zeliwdOBPAZWUwEdj +QEqlYCJWwPhQe2cHWwVPnNHtp+66pEJs+lVeqM/IMxcJZhHevoF8T0M02WtIOgAc +5/oGrdV092cN0aRGlI1bCmEqm6yrP+KIpQHSNhmugkkZzpJ/Ei50446AxuE0VHL1 +5UZ8A9+VkPn0AsbuMPU5 +-----END PUBLIC KEY----- diff --git a/OSX/update-info-plist.pl b/OSX/update-info-plist.pl new file mode 100755 index 00000000..0d933cb7 --- /dev/null +++ b/OSX/update-info-plist.pl @@ -0,0 +1,410 @@ +#!/usr/bin/perl -w +# Copyright © 2006-2013 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. +# +# Updates the NAME.xml file of a .saver bundle to include the current year, +# version number, etc. Also updates the Info.plist file to include the +# short documentation, authors, etc. in the Finder "Get Info" properties. +# +# This is invoked by a final "Shell Script" build action on each of the +# .saver targets in the XCode project. +# +# Created: 8-Mar-2006. + +require 5; +#use diagnostics; # Fails on some MacOS 10.5 systems +use strict; +use IPC::Open3; +use IO::Uncompress::Gunzip qw(gunzip $GunzipError); +use IO::Compress::Gzip qw(gzip $GzipError); + +my ($exec_dir, $progname) = ($0 =~ m@^(.*?)/([^/]+)$@); + +my $version = q{ $Revision: 1.28 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; + +$ENV{PATH} = "/usr/local/bin:$ENV{PATH}"; # for seticon + +my $thumbdir = $ENV{HOME} . '/www/xscreensaver/screenshots/'; + + + +my $verbose = 1; + +sub convert_plist($$) { + my ($data, $to_binary_p) = @_; + my $is_binary_p = ($data =~ m/^bplist/s); + if ($data && (!$is_binary_p) != (!$to_binary_p)) { + print STDERR "$progname: converting plist\n" if ($verbose > 2); + my $which = ($to_binary_p ? 'binary1' : 'xml1'); + my $cmd = "plutil -convert $which -s -o - -"; + my $pid = open3 (my $in, my $out, undef, $cmd) || error ("pipe: $cmd: $!"); + print $in $data; + close $in; + local $/ = undef; # read entire file + $data = <$out>; + close $out; + } + return $data; +} + + +sub read_info_plist($) { + my ($app_dir) = @_; + my $file = "$app_dir/Contents/Info.plist"; + my $file2 = "$app_dir/Info.plist"; + $file =~ s@/+@/@g; + my $in; + if (open ($in, '<', $file)) { + } elsif (open ($in, '<', $file2)) { + $file = $file2; + } else { + error ("$file: $!"); + } + print STDERR "$progname: read $file\n" if ($verbose > 2); + local $/ = undef; # read entire file + my $body = <$in>; + close $in; + + $body = convert_plist ($body, 0); # convert to xml plist + return ($file, $body); +} + + +sub read_saver_xml($) { + my ($app_dir) = @_; + error ("$app_dir: no name") + unless ($app_dir =~ m@/([^/.]+).(app|saver)/?$@x); + my $name = $1; + + return () if ($name eq 'XScreenSaver'); + return () if ($name eq 'SaverTester'); + return () if ($name eq 'XScreenSaverUpdater'); + + my $file = "$app_dir/Contents/Resources/" . lc($name) . ".xml"; + my $file2 = "$app_dir/" . lc($name) . ".xml"; + my $file3 = "$app_dir/Contents/PlugIns/$name.saver/Contents/Resources/" . + lc($name) . ".xml"; + $file =~ s@/+@/@g; + my $in; + if (open ($in, '<', $file)) { + } elsif (open ($in, '<', $file2)) { $file = $file2; + } elsif (open ($in, '<', $file3)) { $file = $file3; + } else { + error ("$file: $!"); + } + print STDERR "$progname: read $file\n" if ($verbose > 2); + local $/ = undef; # read entire file + my $body = <$in>; + close $in; + + # Uncompress the XML if it is compressed. + my $body2 = ''; + gunzip (\$body, \$body2) || error ("$app_dir: xml gunzip: $GunzipError"); + my $was_compressed_p = ($body ne $body2); + return ($file, $body2, $was_compressed_p); +} + + +sub update_saver_xml($$) { + my ($app_dir, $vers) = @_; + my ($filename, $body, $was_compressed_p) = read_saver_xml ($app_dir); + my $obody = $body; + + return () unless defined ($filename); + + $body =~ m@]*?[ \t]_label=\"([^\"]+)\"@m || + error ("$filename: no name label"); + my $name = $1; + + $body =~ m@<_description>(.*?)@s || + error ("$filename: no description tag"); + my $desc = $1; + $desc =~ s/^([ \t]*\n)+//s; + $desc =~ s/\s*$//s; + + # in case it's done already... + $desc =~ s@@@gs; + $desc =~ s/^.* version \d[^\n]*\n//s; + $desc =~ s/^From the XScreenSaver.*\n//m; + $desc =~ s@^http://www\.jwz\.org/xscreensaver.*\n@@m; + $desc =~ + s/\nCopyright [^ \r\n\t]+ (\d{4})(-\d{4})? (.*)\.$/\nWritten $3; $1./s; + $desc =~ s/^\n+//s; + + error ("$filename: description contains bad characters") + if ($desc =~ m/([^\t\n -~]|[<>])/); + + error ("$filename: can't extract authors") + unless ($desc =~ m@^(.*)\nWritten by[ \t]+(.+)$@s); + $desc = $1; + my $authors = $2; + $desc =~ s/\s*$//s; + + my $year = undef; + if ($authors =~ m@^(.*?)\s*[,;]\s+(\d\d\d\d)([-\s,;]+\d\d\d\d)*[.]?$@s) { + $authors = $1; + $year = $2; + } + + error ("$filename: can't extract year") unless $year; + my $cyear = 1900 + ((localtime())[5]); + $year = "$cyear" unless $year; + if ($year && ! ($year =~ m/$cyear/)) { + $year = "$year-$cyear"; + } + + $authors =~ s/[.,;\s]+$//s; + + # List me as a co-author on all of them, since I'm the one who + # did the OSX port, packaged it up, and built the executables. + # + my $curator = "Jamie Zawinski"; + if (! ($authors =~ m/$curator/si)) { + if ($authors =~ m@^(.*?),? and (.*)$@s) { + $authors = "$1, $2, and $curator"; + } else { + $authors .= " and $curator"; + } + } + + my $desc1 = ("$name, version $vers.\n\n" . # savername.xml + $desc . "\n" . + "\n" . + "From the XScreenSaver collection: " . + "http://www.jwz.org/xscreensaver/\n" . + "Copyright \302\251 $year by $authors.\n"); + + my $desc2 = ("$name $vers,\n" . # Info.plist + "\302\251 $year $authors.\n" . + "From the XScreenSaver collection:\n" . + "http://www.jwz.org/xscreensaver/\n" . + "\n" . + $desc . + "\n"); + + # unwrap lines, but only when it's obviously ok: leave blank lines, + # and don't unwrap if that would compress leading whitespace on a line. + # + $desc2 =~ s/^(From |http:)/\n$1/gm; + 1 while ($desc2 =~ s/([^\s])[ \t]*\n([^\s])/$1 $2/gs); + $desc2 =~ s/\n\n(From |http:)/\n$1/gs; + + $body =~ s@(<_description>)(.*?)()@$1$desc1$3@s; + + # NSXMLParser doesn't seem to work properly on Latin1 XML documents, + # so we convert these to UTF8 when embedding them in the .saver bundle. + $body =~ s@encoding="ISO-8859-1"@encoding="UTF-8"@gsi; + + if ($obody eq $body && $was_compressed_p) { + print STDERR "$progname: $filename: unchanged\n" if ($verbose > 1); + } else { + + # Gzip the XML. + my $body2 = ''; + gzip (\$body, \$body2) || error ("$app_dir: xml gzip: $GzipError"); + $body = $body2; + + my $file_tmp = "$filename.tmp"; + open (my $out, '>:raw', $file_tmp) || error ("$file_tmp: $!"); + print $out $body || error ("$file_tmp: $!"); + close $out || error ("$file_tmp: $!"); + + if (!rename ("$file_tmp", "$filename")) { + unlink "$file_tmp"; + error ("mv \"$file_tmp\" \"$filename\": $!"); + } + print STDERR "$progname: wrote $filename\n" if ($verbose); + } + + return ($desc1, $desc2); +} + + +sub compress_all_xml_files($) { + my ($dir) = @_; + opendir (my $dirp, $dir) || error ("$dir: $!"); + my @files = readdir ($dirp); + closedir $dirp; + foreach my $f (sort @files) { + next unless ($f =~ m/\.xml$/si); + my $filename = "$dir/$f"; + open (my $in, '<', $filename) || error ("$filename: $!"); + print STDERR "$progname: read $filename\n" if ($verbose > 2); + local $/ = undef; # read entire file + my $body = <$in>; + close $in; + + if ($body =~ m/^<\?xml/s) { + my $body2 = ''; + gzip (\$body, \$body2) || error ("$filename: xml gzip: $GzipError"); + $body = $body2; + my $file_tmp = "$filename.tmp"; + open (my $out, '>:raw', $file_tmp) || error ("$file_tmp: $!"); + print $out $body || error ("$file_tmp: $!"); + close $out || error ("$file_tmp: $!"); + + if (!rename ("$file_tmp", "$filename")) { + unlink "$file_tmp"; + error ("mv \"$file_tmp\" \"$filename\": $!"); + } + print STDERR "$progname: compressed $filename\n" if ($verbose); + } elsif ($verbose > 2) { + print STDERR "$filename: already compressed\n"; + } + } +} + + +sub set_plist_key($$$$) { + my ($filename, $body, $key, $val) = @_; + + if ($body =~ m@^(.* + \n\t$key + \n\t)([^<>]*)( + .*)$@xs) { +# print STDERR "$progname: $filename: $key was: $2\n" if ($verbose); + $body = $1 . $val . $3; + } else { + error ("$filename: unparsable") + unless ($body =~ m@^(.*)(\n\n\n)$@s); + $body = ($1 . + "\n\t$key" . + "\n\t$val" . + $2); + } + + return $body; +} + + +sub set_icon($) { + my ($app_dir) = @_; + $app_dir =~ s@/+$@@s; + + # "seticon" is from osxutils, http://osxutils.sourceforge.net/ + + my $icon = ($app_dir =~ m/\.saver$/ ? 'XScreenSaver' : 'SaverRunner'); + $icon = "$app_dir/../../../$icon.icns"; + my @cmd = ("seticon", "-d", $icon, $app_dir); + print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" + if ($verbose > 1); + system (@cmd); +} + + +sub set_thumb($) { + my ($app_dir) = @_; + + return unless ($app_dir =~ m@\.saver/?$@s); + + my @cmd = ("$exec_dir/update-thumbnail.pl", $thumbdir, $app_dir); + push @cmd, "-" . ("v" x $verbose) if ($verbose); + print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" + if ($verbose > 1); + system (@cmd); + my $exit = $? >> 8; + exit ($exit) if $exit; +} + + +sub update($) { + my ($app_dir) = @_; + + error ("$app_dir: no name") + unless ($app_dir =~ m@/([^/.]+).(app|saver)/?$@x); + my $app_name = $1; + + my ($filename, $plist) = read_info_plist ($app_dir); + my $oplist = $plist; + + error ("$filename: no version number") + unless ($plist =~ m@CFBundleShortVersionString\s* + ([^<>]+)@sx); + my $vers = $1; + my ($ignore, $info_str) = update_saver_xml ($app_dir, $vers); + + # No, don't do this -- the iOS version reads the XML file in a few + # different places, and most of those places don't understand gzip. + + if ($app_name eq 'XScreenSaver') { + compress_all_xml_files ($app_dir); + } elsif (! defined($info_str)) { + print STDERR "$progname: $filename: no XML file\n" if ($verbose > 1); + } else { + + $info_str =~ m@^([^\n]+)\n@s || + error ("$filename: unparsable copyright"); + my $copyright = "$1"; + $copyright =~ s/\b\d{4}-(\d{4})\b/$1/; + + # Lose the Wikipedia URLs. + $info_str =~ s@http:.*?\b(wikipedia|mathworld)\b[^\s]+[ \t]*\n?@@gm; + + $info_str =~ s/(\n\n)\n+/$1/gs; + $info_str =~ s/(^\s+|\s+$)//gs; + $plist = set_plist_key ($filename, $plist, + "NSHumanReadableCopyright", $copyright); + $plist = set_plist_key ($filename, $plist, + "CFBundleLongVersionString",$copyright); + $plist = set_plist_key ($filename, $plist, + "CFBundleGetInfoString", $info_str); + + if ($oplist eq $plist) { + print STDERR "$progname: $filename: unchanged\n" if ($verbose > 1); + } else { + $plist = convert_plist ($plist, 1); # convert to binary plist + my $file_tmp = "$filename.tmp"; + open (my $out, '>:raw', $file_tmp) || error ("$file_tmp: $!"); + print $out $plist || error ("$file_tmp: $!"); + close $out || error ("$file_tmp: $!"); + + if (!rename ("$file_tmp", "$filename")) { + unlink "$file_tmp"; + error ("mv \"$file_tmp\" \"$filename\": $!"); + } + print STDERR "$progname: wrote $filename\n" if ($verbose); + } + } + + set_icon ($app_dir); + set_thumb ($app_dir); +} + + +sub error($) { + my ($err) = @_; + print STDERR "$progname: $err\n"; + exit 1; +} + +sub usage() { + print STDERR "usage: $progname [--verbose] program.app ...\n"; + exit 1; +} + +sub main() { + + my @files = (); + while ($_ = $ARGV[0]) { + shift @ARGV; + if (m/^--?verbose$/s) { $verbose++; } + elsif (m/^-v+$/) { $verbose += length($_)-1; } + elsif (m/^--?q(uiet)?$/s) { $verbose = 0; } + elsif (m/^-/s) { usage(); } + else { push @files, $_; } + } + usage() unless ($#files >= 0); + foreach (@files) { + update ($_); + } +} + +main(); +exit 0; diff --git a/OSX/update-thumbnail.pl b/OSX/update-thumbnail.pl new file mode 100755 index 00000000..1f5eccee --- /dev/null +++ b/OSX/update-thumbnail.pl @@ -0,0 +1,165 @@ +#!/usr/bin/perl -w +# Copyright © 2006-2013 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. +# +# Converts and installs a thumbnail image inside a .saver bundle. +# +# Created: 26-Jul-2012. + +require 5; +#use diagnostics; # Fails on some MacOS 10.5 systems +use strict; + +my $progname = $0; $progname =~ s@.*/@@g; +my $version = q{ $Revision: 1.3 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; + +my $verbose = 1; + +$ENV{PATH} = "/opt/local/bin:$ENV{PATH}"; # MacPorts, for ImageMagick + + +sub safe_system(@) { + my @cmd = @_; + system (@cmd); + my $exit_value = $? >> 8; + my $signal_num = $? & 127; + my $dumped_core = $? & 128; + error ("$cmd[0]: core dumped!") if ($dumped_core); + error ("$cmd[0]: signal $signal_num!") if ($signal_num); + error ("$cmd[0]: exited with $exit_value!") if ($exit_value); +} + + +# Returns true if the two files differ (by running "cmp") +# +sub cmp_files($$) { + my ($file1, $file2) = @_; + + my @cmd = ("cmp", "-s", "$file1", "$file2"); + print STDERR "$progname: executing \"" . join(" ", @cmd) . "\"\n" + if ($verbose > 3); + + system (@cmd); + my $exit_value = $? >> 8; + my $signal_num = $? & 127; + my $dumped_core = $? & 128; + + error ("$cmd[0]: core dumped!") if ($dumped_core); + error ("$cmd[0]: signal $signal_num!") if ($signal_num); + return $exit_value; +} + + +sub update($$) { + my ($src_dir, $app_dir) = @_; + + # Apparently Apple wants Resources/{thumbnail.png to be 90x58, + # and Resources/thumbnail@2x.png to be 180x116. Let's just + # make the former, but make it be the latter's size. + # + my $size = '180x116'; + + error ("$app_dir does not exist") unless (-d $app_dir); + error ("$app_dir: no name") + unless ($app_dir =~ m@/([^/.]+).(saver|app)/?$@x); + my $app_name = $1; + + $app_dir =~ s@/+$@@s; + $app_dir .= "/Contents/Resources"; + + error ("$app_dir does not exist") unless (-d $app_dir); + my $target = "$app_dir/thumbnail.png"; + + $src_dir .= "/" unless ($src_dir =~ m@/$@s); + my $src_dir2 = "${src_dir}retired/"; + + $app_name =~ s/rdbomb/rd-bomb/si; # sigh + + my $img = $src_dir . lc($app_name) . ".jpg"; + my $img2 = $src_dir2 . lc($app_name) . ".jpg"; + $img = $img2 if (! -f $img && -f $img2); + error ("$img does not exist") unless (-f $img); + + my $tmp = sprintf ("%s/thumb-%08x.png", + ($ENV{TMPDIR} ? $ENV{TMPDIR} : "/tmp"), + rand(0xFFFFFFFF)); + my @cmd = ("convert", + $img, + "-resize", $size . "^", + "-gravity", "center", + "-extent", $size, + "-quality", "95", # saves 8% + "+dither", "-colors", "128", # Saves an additional 61% + $tmp); + + print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" + if ($verbose > 2); + safe_system (@cmd); + + if (! -s $tmp) { + unlink $tmp; + error ("failed: " . join(" ", @cmd)); + } + + # This only saves 0.4% on top of the above. + # @cmd = ("optipng", "-quiet", "-o7", $tmp); + # print STDERR "$progname: exec: " . join(' ', @cmd) . "\n" + # if ($verbose > 2); + # safe_system (@cmd); + + if (! -s $tmp) { + unlink $tmp; + error ("failed: " . join(" ", @cmd)); + } + + if (! cmp_files ($tmp, $target)) { + unlink $tmp; + print STDERR "$progname: $target: unchanged\n" if ($verbose > 1); + } elsif (! rename ($tmp, $target)) { + unlink $tmp; + error ("mv $tmp $target: $!"); + } else { + print STDERR "$progname: wrote $target\n" if ($verbose); + } +} + + +sub error($) { + my ($err) = @_; + print STDERR "$progname: $err\n"; + exit 1; +} + +sub usage() { + print STDERR "usage: $progname [--verbose] image-dir program.app ...\n"; + exit 1; +} + +sub main() { + + my $src_dir; + my @files = (); + while ($_ = $ARGV[0]) { + shift @ARGV; + if (m/^--?verbose$/s) { $verbose++; } + elsif (m/^-v+$/) { $verbose += length($_)-1; } + elsif (m/^--?q(uiet)?$/s) { $verbose = 0; } + elsif (m/^-/s) { usage(); } + elsif (! $src_dir) { $src_dir = $_; } + else { push @files, $_; } + } + usage() unless ($src_dir && $#files >= 0); + foreach (@files) { + update ($src_dir, $_); + } +} + +main(); +exit 0; diff --git a/OSX/updates.pl b/OSX/updates.pl new file mode 100755 index 00000000..c1bfd246 --- /dev/null +++ b/OSX/updates.pl @@ -0,0 +1,215 @@ +#!/usr/bin/perl -w +# Copyright © 2013 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. +# +# Generates updates.xml from README, archive/, and www/. +# +# Created: 27-Nov-2013. + +require 5; +use diagnostics; +use strict; + +use open ":encoding(utf8)"; +use POSIX; + +my $progname = $0; $progname =~ s@.*/@@g; +my $version = q{ $Revision: 1.1 $ }; $version =~ s/^[^\d]+([\d.]+).*/$1/; + +my $verbose = 0; +my $debug_p = 0; + +my $base_url = "http://www.jwz.org/"; +my $priv_key_file = "$ENV{HOME}/.ssh/sparkle_dsa_priv.pem"; +my $sign_update = "./sign_update.rb"; + + +sub generate_xml($$$$) { + my ($app_name, $changelog, $archive_dir, $www_dir) = @_; + + my $outfile = "updates.xml"; + + my $obody = ''; + my %sigs; + my %dates; + if (open (my $in, '<', $outfile)) { + print STDERR "$progname: reading $outfile\n" if $verbose; + local $/ = undef; # read entire file + $obody = <$in>; + close $in; + foreach my $item (split (/(.*?) 1); + } + } + + open (my $in, '<', $changelog) || error ("$changelog: $!"); + print STDERR "$progname: reading $changelog\n" if $verbose; + local $/ = undef; # read entire file + my $body = <$in>; + close $in; + + my $rss = ""; + + $body =~ s/^(\d+\.\d+[ \t])/\001$1/gm; + my @log = split (/\001/, $body); + shift @log; + foreach my $log (@log) { + my ($v1, $entry) = ($log =~ m/^(\d+\.\d+)\s+(.*)$/s); + + $entry =~ s/^\s*\d\d?[- ][A-Z][a-z][a-z][- ]\d{4}:?\s+//s; # lose date + + $entry =~ s/^\s+|\s+$//gs; + $entry =~ s/^\s+|\s+$//gm; + $entry =~ s/^[-*] /
    • /gm; + $entry =~ s/^
    //si; + $entry =~ s/\s+/ /gs; + + my $v2 = $v1; $v2 =~ s/\.//gs; + my $zip = undef; + DONE: + foreach my $ext ('zip', 'dmg', 'tar.gz', 'tar.Z') { + foreach my $v ($v1, $v2) { + foreach my $name ($app_name, "x" . lc($app_name)) { + my $f = "$name-$v.$ext"; + if (-f "$archive_dir/$f") { + $zip = $f; + last DONE; + } + } + } + } + + my $url = ("${base_url}$app_name/" . + ($zip && -f "$www_dir/$zip" ? $zip : "")); + + $url =~ s@DaliClock/@xdaliclock/@gs if $url; # Kludge + + my @st = stat("$archive_dir/$zip") if $zip; + my $size = $st[7]; + my $date = $st[9]; + $date = ($zip ? + strftime ("%a, %d %b %Y %T %z", localtime($date)) + : ""); + + my $odate = $dates{$v1}; + my $sig = $sigs{$v1}; + # Re-generate the sig if the file date changed. + $sig = undef if ($odate && $odate ne $date); + + print STDERR "$progname: $v1: $date " . ($sig ? "Y" : "N") . "\n" + if ($verbose > 1); + + if (!$sig && $zip) { + local %ENV = %ENV; + $ENV{PATH} = "/usr/bin:$ENV{PATH}"; + $sig = `$sign_update "$archive_dir/$zip" "$priv_key_file"`; + $sig =~ s/\s+//gs; + } + + my $enc = ($zip && -f "$www_dir/$zip" + ? ("\n") + : "$v1\n"); + + $enc =~ s/^/ /gm if $enc; + my $item = ("\n" . + " Version $v1\n" . + " $url\n" . + " \n" . + " $date\n" . + $enc . + "\n"); + $item =~ s/^/ /gm; + + # I guess Sparkle doesn't like info-only items. + $item = '' unless ($zip && -f "$www_dir/$zip"); + + $rss .= $item; + } + + $rss = ("\n" . + "\n" . + " \n" . + " $app_name updater\n" . + " ${base_url}$app_name/updates.xml\n" . + " Updates to $app_name.\n" . + " en\n" . + $rss . + " \n" . + "\n"); + + if ($rss eq $obody) { + print STDERR "$progname: $outfile: unchanged\n"; + } else { + my $tmp = "$outfile.tmp"; + open (my $out, '>', $tmp) || error ("$tmp: $!"); + print $out $rss; + close $out; + if ($debug_p) { + system ("diff", "-wNU2", "$outfile", "$tmp"); + unlink $tmp; + } else { + if (!rename ("$tmp", "$outfile")) { + unlink "$tmp"; + error ("mv $tmp $outfile: $!"); + } else { + print STDERR "$progname: wrote $outfile\n"; + } + } + } +} + + +sub error($) { + my ($err) = @_; + print STDERR "$progname: $err\n"; + exit 1; +} + +sub usage() { + print STDERR "usage: $progname [--verbose] app-name changelog archive www\n"; + exit 1; +} + +sub main() { + my ($app_name, $changelog, $archive_dir, $www_dir); + while ($#ARGV >= 0) { + $_ = shift @ARGV; + if (m/^--?verbose$/) { $verbose++; } + elsif (m/^-v+$/) { $verbose += length($_)-1; } + elsif (m/^--?debug$/) { $debug_p++; } + elsif (m/^-./) { usage; } + elsif (!$app_name) { $app_name = $_; } + elsif (!$changelog) { $changelog = $_; } + elsif (!$archive_dir) { $archive_dir = $_; } + elsif (!$www_dir) { $www_dir = $_; } + else { usage; } + } + + usage unless $www_dir; + generate_xml ($app_name, $changelog, $archive_dir, $www_dir); + +} + +main(); +exit 0; diff --git a/OSX/updates.xml b/OSX/updates.xml new file mode 100644 index 00000000..ef7295bc --- /dev/null +++ b/OSX/updates.xml @@ -0,0 +1,44 @@ + + + + xscreensaver updater + http://www.jwz.org/xscreensaver/updates.xml + Updates to xscreensaver. + en + + Version 5.25 + http://www.jwz.org/xscreensaver/xscreensaver-5.25.dmg + • Some files were missing from the tarball.]]> + Mon, 09 Dec 2013 00:38:35 -0800 + + + + Version 5.24 + http://www.jwz.org/xscreensaver/xscreensaver-5.24.dmg + • Updated feed-loading for recent Flickr changes.
    • Updated `webcollage' for recent Google changes.
    • Added Instagram and Bing as `webcollage' image sources.
    • Updated to latest autoconf.
    • Bug fixes.]]>
    + Sat, 07 Dec 2013 19:06:56 -0800 + +
    + + Version 5.14 + http://www.jwz.org/xscreensaver/xscreensaver-5.14.dmg + • Added "Quick Power-off in Blank Only Mode" option.
    • BSOD GLaDOS.]]>
    + Fri, 20 May 2011 11:42:36 -0700 + +
    +
    +
    diff --git a/OSX/xscreensaver_Prefix.pch b/OSX/xscreensaver_Prefix.pch new file mode 100644 index 00000000..07c8c89b --- /dev/null +++ b/OSX/xscreensaver_Prefix.pch @@ -0,0 +1,33 @@ +/* Prefix header for all source files of the 'xscreensaver' project. + */ + +#include +#include +#include +#include + +#include + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +# undef USE_IPHONE +# define USE_IPHONE +# define HAVE_JWZGLES +#endif + +#ifdef __OBJC__ +# ifdef USE_IPHONE +# import +# import +# else +# import +# endif +#endif + +#include "jwxyz.h" + +# ifdef USE_IPHONE +# include +# include +#else +# include +#endif diff --git a/README b/README new file mode 100644 index 00000000..454e4cbb --- /dev/null +++ b/README @@ -0,0 +1,1475 @@ + + XScreenSaver + + a collection of + free screen savers + for X11 and MacOS + + By Jamie Zawinski + and many others + + http://www.jwz.org/xscreensaver/ + +=============================================================================== + +This is the XScreenSaver source code distribution. It is strongly recommended +that you install a binary release rather than trying to compile it yourself. +Binaries are available for almost all platforms, including MacOS X. See the +XScreenSaver web site for details. + +To compile on a Unix system with X11: + + ./configure + make + make install + +To compile on MacOS X: + + Use the included XCode project. Requires XCode 4 and MacOS X 10.5 + or newer. + +Interested in writing a new screen saver? + + See the README.hacking file. + +=============================================================================== + +XScreenSaver has an extensive manual -- please read it! + +=============================================================================== + +5.25 * Try harder to bypass Quarrantine and Gatekeeper in OSX installer. + * Some files were missing from the tarball. + +5.24 * Added "Automatically check for updates" option on OSX. + * Updated feed-loading for recent Flickr changes. + * Updated `webcollage' for recent Google changes. + * Added Instagram and Bing as `webcollage' image sources. + * Updated to latest autoconf. + * Bug fixes. + +5.23 * New hack, `geodesic'. + * iOS and OSX: huge XCopyArea performance improvements. + * More heuristics for using RSS feeds as image sources. + * Improved Wikipedia parser. + * Updated `webcollage' for recent Flickr changes. + * Added Android to `bsod'. + * OSX: Added a real installer. + * iOS and OSX: fixed a font-metrics bug. + * iOS: Fixed aspect ratio bug in non-rotating apps when launched in + landscape mode. + * Made `quasicrystal' work on weak graphics cards. + * iOS: fixed `ifs'. + * Better compression on icons, plists and XML files: smaller + distribution and installation footprint. + * Reverted that DEACTIVATE change. Bad idea. + * `Phosphor' now supports amber as well as green. + +5.22 * New hacks, `kaleidocycle', `quasicrystal', `unknownpleasures' and + `hexadrop'. + * Performance improvements for `interference'. + * Fixed possible crashes in `apple2', `maze', `pacman', `polyominoes', + `fireworkx', `engine'. + * Fix for `bumps' in 64 bit. + * Fixed preferences crash on old iOS 5 devices. + * Fixed "Shake to Randomize"; display name of saver. + * Fixed weirdness with "Frame Rate" sliders on iOS. + * Fixed rotation problems with `pacman', `decayscreen'. + * Better dragging in `fluidballs'. + * Ignore rotation in hacks that don't benefit from it. + * Ignore DEACTIVATE messages when locked, instead of popping up the + password dialog box. + +5.21 * Changed default text source from Twitter to Wikipedia, since Twitter + now requires a login to get any feeds. + * New version of `fireworkx'. + * Minor fixes to `distort', `fontglide', `xmatrix'. + * New MacOS crash in `bsod'. + * New mode in `lcdscrub'. + +5.20 * Support for iPhone 5 screen size. + * Fixed modifier key handing in Apple2.app and Phosphor.app on MacOS. + * Various minor bug fixes. + +5.19 * MacOS 10.8.0 compatibility. + * iOS performance improvements. + +5.18 * iOS responds to shake gestures to randomize. + * iOS can load images from your Photo Library. + * iOS has clickable Wikipedia links in Settings panels. + * Made `pipes' be ridiculously less efficient, but spin. + * Added better mouse control to `rubik', `cube21', `crackberg', and + `julia'. + * Cosmetic improvements to `queens' and `endgame'. + * `sonar' can now ping local subnet on DHCP. + * Most savers now resize/rotate properly. + * Various fixes. + +5.17 * More iOS tweaks. + * Fixed some compilation problems. + * Enlarged the texture image for `lament'. + +5.16 * Ported to iPhone and iPad. + * XInput devices now also ignore small mouse motions. + * Loading images via RSS feeds is much improved. + * Various minor fixes. + +5.15 * New hacks, `hilbert', `companioncube' and `tronbit'. + * Image-manipulating hacks can now load from RSS or Atom feeds: + `imageDirectory' may contain a URL. + * Updated `webcollage' for recent search engine changes. + * `phosphor' and `apple2' can now be run as standalone terminal + emulator applications on MacOS. + * `photopile' sped up. + * New molecule in `molecule'. + * "Upgraded" to XCode 4.0, which means that MacOS 10.4 PPC builds are + impossible, and Intel is now required. + * Turned on LC_CTYPE on Linux; maybe Japanese password entry works + now? + +5.14 * Fixed crash in Blank Only Mode when DPMS disabled. + * Added "Quick Power-off in Blank Only Mode" option. + * BSOD GLaDOS. + +5.13 * Optionally enabled full-scene OpenGL antialiasing. Set the resource + `*multiSample' to true if doing so doesn't kill performance with + your video hardware. + * New version of `glhanoi'. + * Image-loading hacks that display the file name now also display the + sub-directory (xscreensaver-getimage now returns relative paths + under imageDirectory). + * Passwords that contain UTF-8 non-Latin1 chars are now typeable. + * Numerous minor stability fixes. + +5.12 * Big speed improvement on OSX for heavy XCopyArea users (`xmatrix', + `moire2', `phosphor', etc.) + * Plugged a bad OSX-only Pixmap leak. + * Kludged around the OSX pty bug that caused text to be truncated in + phosphor, starwars, apple2, etc. + * New molecule in `molecule'. + * `glhanoi' now supports an arbitrary number of poles. + * Turned on "New Login" button by default. + * Added support for XInput-style alternate input devices. + +5.11 * New versions of `photopile', `strange'. + * Worked around MacOS 10.6 garbage collector bug that caused the + screen saver process to become enormous. + * Fixed flicker in `pipes', `cubestorm', and `noof'. + * Fixed EXIF rotation on MacOS 10.6. + * Fixed desktop-grabbing when screen locked on MacOS. + * Minor fixes to `circuit', `polyhedra', `tangram', `gears', `pinion', + `substrate', `xanalogtv'. + * Fixed some leaks in `xanalogtv' and `apple2'. + * Better seeding of the RNG. + +5.10 * Fixed some crashes and color problems on MacOS 10.6. + * Retired `hypercube' and `hyperball', which are redundant with + `polytopes'. + + +5.09 * Ported to MacOS 10.6, including various 64-bit fixes. + * New hack, `rubikblocks'. + * Fixed another potential RANDR crash. + * Use correct proxy server on MacOS. + * `molecule' now correctly displays PDB 3.2 files. + * Updates to `mirrorblob', `glhanoi', and `sonar'. + * Rewritten version of `klein' hack. + * New hack, `surfaces', incorporating objects from old `klein' hack, + plus new ones. + * Merged `juggle' and `juggler3d' hacks. + * Fixed compilation under gcc 4.4.0 (strict aliasing). + * Fixed intermittent failure in `xscreensaver-command'. + +5.08 * New hack, `photopile'. + * Rewrote `sonar' and `jigsaw' as OpenGL programs. + * Minor tweaks to `maze', `m6502', `hypnowheel', and `timetunnel'. + * Savers that load images now obey EXIF rotation tags. + * Arrgh, more RANDR noise! Fixes this time for rotated screens, and + for systems where RANDR lies and says the screen size is 0x0. + * When the password dialog has timed out or been cancelled, don't pop + it right back up a second time. + * Password timeouts/cancels don't count as "failed logins". + * Retired some of the older, less interesting savers: say goodbye to + `bubbles', `critical', `flag', `forest', `glforestfire', `lmorph', + `laser', `lightning', `lisa', `lissie', `rotor', `sphere', `spiral', + `t3d', `vines', `whirlygig', and `worm'. + * Merged `munch' and `mismunch'. + * Updated `webcollage' to use twitpic.com as well. + +5.07 * Xinerama/RANDR tweaks for old-style multi-screen. + * Added bumpy skin and cel shading to `skytentacles'. + * `flipflop' can load images onto the tiles. + * Fixed the bouncing ball in `stairs'. + * Added the missing Utah Teapotahedron to `polyhedra'. + * `blitspin' works with color images on MacOS now. + * Added transparency to `stonerview'. + * Improved layout of the preferences dialogs: they should all now be + usable even on ridiculously tiny laptop screens. + * MacOS preferences text fields now prevent you from entering numbers + that are out of range. + * Added "Reset to Defaults" button on X11. + * Added relevant Wikipedia links to many of the screen saver + descriptions. + * All hacks support the `-fps' option, not just GL ones. + * The `-fps' option now shows CPU load. + +5.06 * Xinerama/RANDR fixes: this time for sure. It should now work to + add/remove monitors or resize screens at any time. + * New hack, `skytentacles'. + * New version of `gleidescope'. + * Added the `-log' option to the xscreensaver daemon, since a truly + shocking number of Linux users seem to have no idea how to redirect + output to a file. + * Added `-duration' arg to most image-loading hacks, so that they pick + a new image every few minutes. + * Added an ATM crash to `bsod'. + +5.05 * New hacks, `cubicgrid', `hypnowheel', and `lcdscrub' (which isn't + really a screen saver). + * Updates to `m6502' and `gears'. + * Fixed double-buffering problems in `cubestorm' and `noof'. + * Better handling of horizontal scroll wheels. + * Attempt to work around latest Xinerama braindamage: if the server + reports overlapping screens, use the largest non-overlapping + rectangles available. + * Don't warning about receipt of bogus ClientMessages, since Gnome's + just never going to stop sending those. + * Worked around MacOS 10.5 perl bug that caused the text-displaying + hacks to fail on some systems. + * Hopefully fixed font-related System Preferences crashes in MacOS + savers. + * The recent PAM changes broke the "Caps Lock" warning in the password + dialog, the failed login warnings, and syslogging. Fixed all that. + +5.04 * Fixed a possible crash in the unlock dialog (more fallout from the + recent PAM changes...) + * New hacks, `moebiusgears', `abstractile', and `lockward'. + * Rewrote `gears' to use better (involute) gear models, and to be more + random. + * Minor updates to `cwaves', `voronoi', `deco', `glcells', `rd-bomb', + `fireworkx' and `webcollage'. + * `pong' can now display the current time as the score. + * `xmatrix -mode pipe' works better. + * Minor tweaks for compilation on MacOS 10.5.0. + +5.03 * New hacks, `cwaves', `glcells', `m6502', and `voronoi'. + * Minor fixes to `bsod'. + * Fixed possible crash with PAM USB-dongle auth. + * Updated `webcollage' to track recent Google Images and Flickr + changes. + +5.02 * Reworked PAM code to support fingerprint readers, etc. + * Ported 'webcollage' to MacOS. + * Added MacOS 10.2 and 10.3 kernel panics to `bsod'. + * Fixed a Xinerama crash when changing the screen count. + * New blobbier `mirrorblob'. + * Minor updates to `lisa', `bsod', `ifs', `hypertorus', `polytopes', + `circuit', `endgame', `crackberg', `flipflop', `flipscreen3d', + `fliptext', and `carousel'. + * Enabled multi-threaded OpenGL on MacOS. + +5.01 * Backed out recent locale-related changes, since they broke far more + things than they fixed. + * Fail gracefully with ridiculously small window sizes. + * `xflame' and `flag' ignore bitmap option on MacOS. + * `speedmine' prefs work on MacOS. + * Better explosions in `boxed'. + * More dynamic motion in `sproingies'. + * More options in `flipflop'. + * Minor updates to `topblock'. + * Various other minor fixes. + +5.00 * Ported to MacOS X! (10.4.0 or newer) + * API change: instead of providing a single screenhack() function that + does not return, screen savers using the screenhack.h framework must + now provide "init" and "draw one frame" functions instead. All + bundled savers have been updated; third-party patches will need + work. + * All image-loading happens asynchronously. + * xscreensaver-getimage-file caches the contents of the image + directory for a few hours, so consecutive runs won't have to re-list + the whole directory tree. + * New hacks, `topblock' and `glschool'. + * Removed `xteevee' (superceded by `xanalogtv'). + * Added variable-sized puzzle pieces to `jigsaw'. + * Changes to the defaults and command-line options of many hacks to + make the .xml files more consistent. + * Reap zombies in `glslideshow' and `carousel'. + * `sonar' works without setuid on MacOS (dgram icmp). + * `xmatrix -mode pipe' displays the text of a subprocess. + * `endgame' has higher resolution chess-piece models. + * `webcollage' takes a -directory option to get images from a local + directory. + * The RPM spec file no longer auto-restarts xscreensaver when a new + version is installed. Restart it manually. + +4.24 * New versions of `cube21', `glsnake', `celtic'. + * Backed out a DPMS-related patch that cause desktop flickering with + some X servers. + * Fixed startup crash in getgroups() when running setuid. + * Default to not displaying stderr on the saver window. + * Fixed bad free() in "Documentation" button. + * Don't try to run hacks that aren't installed. + * Minor fixes to various XML config files and man pages. + +4.23 * New hacks, `glhanoi', `cube21', `timetunnel', `juggler3d', and + `celtic'. + * New versions of `tangram', `webcollage', `hypertorus', `polytopes', + and `ripples'. + * `sonar' is now quiet about unresolvable hosts. + * Minor corrections to BASIC code in `apple2'. + * xscreensaver-demo now provides an RPM clue when none of the hacks + seem to be installed. + * Don't install `ant' by default, since there is some Java tool of + that name, which was causing confusion. And also it's boring. + * Made screen grabbing work again on MacOS 10.4.2. + * No longer prints bogus warnings about ClientMessages intended for + the window manager. + * Ignore unprintable characters in passwd entry field. + * Fixed yet another cross-host-display image-loading endian problem. + * `xscreensaver-command -watch' and `-time' now work on 64-bit + machines. + +4.22 * Fixed a bug in the new mouse-motion code that caused the screen to + never blank on multi-head non-Xinerama systems. Oops. + * New hacks, `interaggregate', `antmaze', `tangram', and `crackberg'. + * Minor tweaks to `fiberlamp', `ifs', `slidescreen', `zoom', `sonar', + `fireworkx', `whirlwindwarp', `bubble3d', and `rd-bomb'. + * Added motion blur to `blinkbox'. + * `bsod' now includes Longhorn's "RSOD", and OS/2. + * Fixed `-wireframe' usage in most hacks and man pages. + +4.21 * New hack: `fliptext'. + * Changed default configure installation directories: /usr/bin/ for + xscreensaver, etc.; /usr/libexec/xscreensaver/ for hacks; + /usr/share/xscreensaver/config/ for xml files. + * All the text-manipulating screen savers can have their text source + configured via `xscreensaver-demo' now. + * xscreensaver.spec now builds three RPMs: base (no hacks); extras (2d + hacks); and gl-extras. + * Added `-program' and `-front' option to `gltext'. + * Added `-shells' to `molecule'. + * Fixed text-alpha glitch in `carousel'. + * New `pacman': the ghosts can be killed now. + * Fixed a bug in screen-grabbing GL hacks where images would be tiled + instead of scaled on machines that can't do large textures. + * `webcollage' can hit Flickr now. + * New (rewritten) implementation of `ifs'. + * The unlock dialog can be made to have a "New Login" button that will + run `gdmflexiserver'. Experimental! + * Fixed non-ASCII display bug in `starwars'. + * Configure finds a default for imageDirectory. + * "xscreensaver-command -lock" now works even if in "screensaver + disabled" mode. + * If a bad password is typed while CapsLock is on, the unlock dialog + says "CapsLock?" instead of "Sorry". + * Mouse motion only counts as activity if the mouse moved more than 10 + pixels (so the screen won't unblank every time you bump your desk.) + * New mode option "random-same": if you have multiple monitors, this + will run the *same* randomly chosen hack on each screen, instead of + different ones on each. + +4.20 * New hacks, `fiberlamp', `boing', `boxfit', and `carousel'. + * Rewrote `glslideshow' again: should be faster now. + * Sped up loading of images in GL programs. + * `starwars' uses texture-mapped fonts now. + * New `bsod' modes: tru64, hppa, and nvidia. + * Updates to `webcollage', `juggle', `pinion', `fireworkx', `sonar', + `extrusion', `substrate', and `pong'. + +4.19 * New hacks, `substrate', `intermomentary', `fireworkx', and `pinion'. + * New version of `flow'. + * Made /proc/interrupts work again on Linux 2.6. + * Made `analogtv' not hog the CPU. + * Made analogtv-based hacks work properly on PPC/ARM. + * Fixed a bad memory leak in `piecewise'. + * Minor updates to `sonar', `molecule', `glmatrix', `galaxy', and + `webcollage'. + * Removed support for GTK 1.x (everyone uses 2.x now.) + +4.18 * Oops, pay no attention to the man behind the curtain. + +4.17 * New hacks, `anemotaxis' and `memscroller'. + * Fixed a bad bug that caused `vidwhacker' to never die. + * Fixed normals and lighting in `polyhedra'. + * Don't reuse the window when changing hacks (to work around bugs in + some GL implementations.) + * Made `xscreensaver-getimage-file' skip thumbnail-sized images. + * Fixed endian problem in `barcode' on non-x86. + * Updates to `webcollage', `apple2', `fuzzyflakes', `atunnel', and + `pacman'. + * Timing tweaks to `bubble3d', `bouncingcow', `engine', `gltext', + `lavalite', `molecule', `spotlight', `sballs', `boxed', `blinkbox', + and `circuit'. + * Configure updates for Fedora core 2 / xorg 6.7.0. + * Compile without warnings under gcc 3.3.3. + * I give up: don't blank or lock the screen if we can't get a keyboard + grab. In that case, both choices are bad. + +4.16 * New hacks, `polyhedra', `fuzzyflakes', `antinspect', and + `providence'. + * Minor updates to `webcollage', `bsod', `endgame', `antspotlight', + `xmatrix', and `glmatrix'. + * Added support for the RANDR (Resize and Rotate) extension to detect + when the size of the desktop has been changed while xscreensaver is + already running. + * Possibly-futile attempt to work around "rdesktop" focus/grab idiocy. + * Made `xscreensaver-getimage -file' still work even if imageDirectory + is unset. + * Convert Latin1 to ASCII in `starwars' and `phosphor' (since the GLUT + font only has ASCII glyphs.) + * Fixed randomization in `noof'. + * Added "GetViewPortIsFullOfLies" preference to work around + longstanding XFree86 bug #421. + * Made `sonar' subnet pinging work properly on bigendian machines + (e.g., PPC.) + +4.15 * New hacks, `wormhole', `mismunch', `noof', and `pacman'. + * `phosphor' and `apple2' include vt100 emulators now: this means you + can do "phosphor -program top", or can use either program as an + xterm replacement: "apple2 -text -fast -program 'xemacs -nw'". + * `analogtv' (and related) fill the screen better. + * The '-gradient' option works in `atlantis' now. + * Minor updates to `blinkbox', `queens', `endgame', `glmatrix', + `mirrorblob', `blocktube', and `molecule'. + * Integrated SuSE's "external passwd helper" support. + * Marginally better /tmp handling in various programs. + * Updated config defaults for xplanet 1.0.3. + * Portability fixes. + +4.14 * New hacks, `fontglide', `apple2', `xanalogtv', `pong', + `gleidescope', `mirrorblob', and `blinkbox'. + * New version of `glsnake' (with many more models.) + * Another Windows crash in `bsod'; also HVX/GCOS6/TPS6. + * New version of `endgame'. + * Screen grabbing works on MacOS X. + * Various minor fixes. + +4.13 * On Xinerama systems, xscreensaver now runs one hack on each monitor + (just like in "real" multi-head mode) instead of running one hack + stretching across all the screens. Note that for this to work with + any 3rd party screensavers, they must update their "vroot.h" file. + * `webcollage' and `vidwhacker' display images using + `xscreensaver-getimage' now. + * Added `ljlatest' script for use with `starwars' and `phosphor'. + +4.12 * New GL hacks, `flipflop', `antspotlight', and `polytopes'. + * Added VMS to `bsod'. + * Compile without warnings in "gcc -pedantic". + * Updates to `webcollage' and `queens'. + * Fixed a bug that could cause PAM to hang. + +4.11 * New hacks, `hypertorus', `cubestorm', `glknots', `blocktube', and + `glmatrix'. + * Updates to `cloudlife', `engine', `xmatrix', and `sonar'. + * Rewrote `glslideshow': it should work on somewhat wimpier video + cards now. + * Various portability tweaks. + +4.10 * New hacks, `cloudlife' and `klein'. + * Added Apple ][+, HPUX, and OS/390 sessions to `bsod'. + * Added some Matrix Reloaded text to `xmatrix'. + * Updates to `webcollage', `eruption', `jigglypuff', `metaballs', and + `endgame'. + * Completely ignore the `memoryLimit' setting now, since it was still + causing people GL grief. + * Various minor fixes. + +4.09 * New hacks, `flyingtoasters', `bouncingcow', `jigglypuff', and + `glslideshow'. + * More models in `engine'. + * Rewrote `xscreensaver-getimage' to remove reliance on external image + loaders (xv, chbg, xloadimage, etc.) and to reduce flicker when + loading files. + * Made `gflux' and `flipscreen3d' be mouse-spinnable. + +4.08 * New hacks, `atunnels' and `piecewise'. + * Physics improvement in `fluidballs'. + * Various fixes for XDarwin systems (X11 on MacOS X.) + * Added -clock option to `barcode'. + * Minor fixes to `endgame', `flurry', `flipscreen3d', and `gflux'. + + +4.07 * New hacks, `flurry', `metaballs', `eruption', `popsquares', and + `barcode'. + * Minor updates to `maze' for high density mazes. + * Added double buffering to `fluidballs' and `whirlygig'. + * Bug fixes for running xscreensaver to a remote XFree86 display + (which nobody would ever do...) + * Updated `webcollage' (faster Alta Vista searching.) + * Updated `glplanet' so the sun sets in the west. + * Updated `sproingies' with smooth, unsegmented surfaces. + * Fixed Perl version-sensitivity in `xscreensaver-getimage-file'. + * Fixed GTK2 scrolling bug in `xscreensaver-demo'. + +4.06 * New hack, `glblur' (disabled by default, since it requires fast + OpenGL texture support.) + * New hack, `halftone'. + * Updates to `endgame', `queens', `bumps', `glplanet', `engine', and + `circuit'. + * New version of `menger' that uses far fewer polygons. + * Fixed minor bug in `critical' that could cause some bogus X servers + to crash. + * Better labels in `molecule': the labels now appear to be attached to + the atoms, instead of floating in front of the whole scene. + * Fixed bug that could rarely cause GL hacks to fail to double-buffer + (causing intermittent flickering.) + * Fixed a relative-URL-parsing bug in `webcollage'. + * Fixed a bug that (sometimes) caused the window manager close box to + kill `xscreensaver-demo' with a crash instead of a graceful exit. + * Updated xscreensaver.pam to the Red Hat 7.3 way. + * More Gnome2-related configure crap. + * Updated to latest `config.guess' and `config.sub'. + * Fixed occasional core dump in `distort'. + * Added a Linux fsck failure and kernel panic to `bsod'. + * Added MacOS X kernel panic to `bsod'. + * Fixed a bug in `bsod' (all bsod bugs are ironic.) + * Fixed a bug that caused `xscreensaver-gl-helper' to print a nonsense + visual ID with some versions of `printf': this could cause GL + programs to display incorrectly (e.g., flickery.) + +4.05 * More `configure' tweaks to try and get things working on systems + that both Gtk 1.x and 2.x installed. + * New hack, `endgame'. + * Minor updates to `gltext'. + +4.04 * Support for GTK 2.x / GNOME 2.x. + * The `configure' script will now use `pkg-config' if you have it, in + preference to `gtk-config', etc. + * New hacks, `lavalite', `queens', and `anemone'. + * Minor updates to `spheremonics', `gltext', `xmatrix'. + * You can use the mouse to manually spin most of the GL hacks now + (when they are displaying in a window.) + * Fixed a bug in `webcollage' (due to recent Alta Vista url changes) + that was causing it to try and load incorrect image URLs. + * Made `xscreensaver-getimage' use gdk_pixbuf if it is available: this + means that those hacks that load images will no longer rely on "xv", + "xloadimage", etc. This will close a race condition that could + sometimes cause your desktop background to be changed; and also + makes it possible for those programs to operate on image files when + running in windowed mode. + * `webcollage' can now be used in conjunction with `driftnet' to + display images snooped from your local ethernet instead of obtained + from search engines. + * Added man pages for all the hacks that didn't have them. + +4.03 * New hack, `spheremonics'. + * Minor updates to `webcollage', `cage', `moebius', `morph3d', + `boxed', `circuit', and `helix'. + * `pulsar' and `extrusion' can now load texture JPEGs. + * `rubik' now does non-square cubes. + * `fluidballs' now does various sizes of balls. + * `menger' and `sierpinski3d' now also show polygon counts in -fps + mode. + * `molecule' displays real subscripts in the formulae. + * GTK internationalization/localization support. + * Better detection of the various versions of libxml. + * Upgraded to autoconf 2.53 (from 2.13.) + +4.02 * Plugged a few minor leaks in `xscreensaver' and `xscreensaver-demo'. + * New hacks, `cubenetic' and `fluidballs'. + * Sped up `pipes'. + * Fixed sphere projection error in `glplanet'; installed a better + image of earth. + * Added Win2K and MacOS 1 crashes to `bsod'. + * Put back previous (better) version of `forest' that was + accidentially downgraded in the last release. + * New version of `bumps'. + * Made FPS computation in GL hacks more efficient: it will influence + the results less, thus resulting in higher (but more accurate) + reported frame rates. + +4.01 * New hacks: `twang', `glsnake', `boxed', `sballs', and + `glforestfire'. + * New hacks `apollonian', `euler2d', `juggle', `polyominoes' and + `thornbird', from xlockmore. + * Merged recent xlockmore changes into `ant', `braid', `demon', + `discrete', `drift', `fadeplot', `forest', `grav', `hopalong', + `ifs', `laser', `lightning', `lisa', `lissie', `loop', `mountain', + `penrose', `rotor', `sierpinski', `slip', `sphere', `spiral', + `strange', and `vines'. + * Fixed the `gltext' bug that sometimes caused horizontal lines to + vanish again. This time for sure. + * Sped up `webcollage' by adding a C helper program to replace the PPM + pipeline. It also pastes images semi-transparently now. + * Added support for the gdk_pixbuf library: if this lib is available, + then `blitspin', `xflame', and `flag' can load GIF, JPEG, and PNG + images in addition to XPM and XBM. + * Fixed a rare race condition where the desktop-grabbing hacks could + sometimes leave the screen wedged, if the user moved the mouse + exactly when they were grabbing the screen image (it would un-wedge + the next time the saver timed out or was activated.) + * Fixed incorrect colors in the screen-grabbing GL hacks (`gflux' and + `flipscreen3d'.) + * Made SIGHUP restart the daemon process (though using + `xscreensaver-command -restart' is still the preferred way.) + * Tweaks to `xspirograph'. + * Minor configure and portability tweaks. + +4.00 * Redesigned `xscreensaver-demo' GUI: it now includes small-preview + and per-hack configuration dialogs. + * Added three new modes of operation: `One Screen Saver', `Blank + Screen', and `Don't Blank' (in addition to the historical `Random + Screen Saver'). + * Configure now defaults to installing the hacks in + /lib/xscreensaver/ instead of /bin/. (Most distros + already did it this way.) + * New GL hacks, `menger', `engine', `flipscreen3d'. + * Made `sierpinski3d' be more colorful. + * New versions of `xmatrix' and `nerverot'. + * Fixed a bug in `starwars' that made the font be drawn with thin + lines in -root mode. + * Fixed a bad colormap bug in `crystal' that could make *subsequent* + hacks malfunction! + * Made `gflux' able to grab screen images (`-mode grab'). + * Updated `webcollage' for recent search engine changes. + * Removed most command-line options to `xscreensaver': just edit the + ~/.xscreensaver file instead. + * Improved behavior on multi-screen and Xinerama systems: the mouse + now stays on the screen where the user left it, and the password and + splash dialogs always appear on the screen that has the mouse. + * Made the splash dialog use more Gtk-like colors; made it have only + two buttons, "Settings" and "Help". + * Made `sonar' understand `.ssh/known_hosts2' format files, and be + better about stripping out illegal addresses. + +3.34 * Turned `memoryLimit' off by default, sigh. Apparently some versions + of the GL libraries (appear to) allocate hundreds of megs for every + GL program, so `memoryLimit' was causing GL programs to malfunction + or crash on those systems. + * Improved fading on TrueColor XFree86 4.1.x systems. + * New GL hack, `circuit'. + * Added `fuzz' mode to `decayscreen'. + * New version of `whirlygig'. + * Added links to `xplanet' and `sphereEversion'. + * Fixed rare race condition that could make `sonar' hang. + * Fixed potential crash in `speedmine'. + * Made `xscreensaver-demo' not crash when imageDirectory was set to a + non-existent directory. + * Made `xscreensaver-getimage-video' invoke XawTV's `streamer' program + better. + * Made `phosphor' and `starwars' deal with CR, LF, or CRLF line + endings. + * Changes for Cygwin compilation environments. + * Made `sonar' compile on systems that can't ping. + * Configure changes for HPUX 10.20. + * Made PAM code work on Red Had 4.2 systems. + * Made `xscreensaver-command -deactivate' work when the saver is not + active: what that does is reset the idle timer, as if keyboard input + had been detected. This was added for the benefit of people writing + DVD-playing software: they can now prevent the screensaver from + kicking in by sending a -deactivate message once a minute while the + movie is playing and not paused. + * Various minor portability tweaks. + +3.33 * New hacks, `speedmine' and `whirlygig'. + * Sped up `pyro', made the explosions look a bit better. + * Added better stars to `glplanet' and `starwars'. + * Many internal changes to `webcollage'. + * Some new options to `attraction'. + * Minor fix to `noseguy' to avoid un-erased pixels. + * Rewrote the screen-eraser effects so that they complete in the same + amount of time regardless of how slow your X server is (some of them + were glacial on servers with slow blitting.) + * Fixed a potential free memory reference that could sometimes cause a + crash at startup. + * Possibly fixed a problem that could cause the daemon to crash with + an X error. I was never able to reproduce this problem, but I think + I might have figured out what caused it. + * Worked around a problem that caused PAM authentication to fail on + some Red Hat 7.x systems. + * Added a `memoryLimit' parameter that controls the amount of memory a + graphics hack may allocate: if they try to allocate more than this, + malloc() will fail (and they will exit or (safely) crash, rather + than hogging memory.) Default is 50M. + * Made `gnome-help-browser' be the default way to display man pages in + `xscreensaver-demo', if running on a GNOME system. + +3.32 * The image-manipulating hacks (`slidescreen', etc.) can now operate + on randomly chosen image files from disk, or on frames captured from + the system's video input, instead of (or in addition to) + manipulating images of the desktop. + * Rewrote `vidwhacker' to use the new image-grabbing mechanism. + * Made fading work on TrueColor XFree86 4.x systems. + * Fixed a subtle rendering bug in `atlantis' (the fish were inside + out!) + * Made `atlantis' have a texture simulating light reflections from the + surface of the ocean. + * Fixed up label placement in `molecule'. + * Better color bars in `xteevee'. + * Made `install-strip' not try to strip scripts. + +3.31 * Put in more sensible defaults for DPMS, and updated the + documentation to reflect the fact that all your DPMS settings are + now belong to xscreensaver. + * Fixed the `xscreensaver.spec' file so that `--force' is no longer + needed. + * New versions of `rotzoomer' and `nerverot'. + * Fixed an OSF/1 compilation problem in `molecule'. + +3.30 * New hacks, `molecule', `dangerball', and `rotzoomer'. + * New version of `gflux'. + * Made `gltext' able to display the current time. + * Fixed a floating-point-precision problem in `gltext' that sometimes + caused horizontal lines to vanish. + * Removed the `-window-id' option from the hacks: it never worked + right, and was unnecessary. + * Made the `starwars' hack use thicker lines, antialias the text, and + fade out at the far edge instead of just dropping off. + * Fixed an SHM segment leak in `moire'. + +3.29 * Better rendering of the new logo. + * New hack, `gltext'. + * Added `-planetary' option to `gears', to draw a different kind of + gear system. + * Made motion and rotation be smoother in `gears', `glplanet', + `moebius', `rubik', and `sierpinski3d'. + * Improved coloration in `sierpinski3d'. + * Made the GL hacks react to window size changes. + * Made most of the GL hacks take a -fps option (like `pulsar' did), so + you can use them to benchmark your 3D hardware. + * Fixed the previous fix to `sonar'. + * Minor fix to `nerverot'. Made sonar able to ping hosts on DEC OSF1. + * Eliminated a bogus "didn't get enough colors" warning in some of the + hacks. + +3.28 * New logo for xscreensaver! + * New hacks, `starwars' and `stonerview'. + * Made the motion of the bouncing ball in `stairs' be a little less + jerky. + * Made newly-added screenhacks be added to .xscreensaver + automatically: if there are hacks in the app-defaults file that are + not also in ~/.xscreensaver, they will be added to the end of the + list. + * Redid the `Screensaver Options' part of the control panel; + xscreensaver now lets you configure your DPMS settings. + * Fixed some Makefile problems with non-GL builds. + * Fixed detection of MesaGL for version 3.3. + * Better workaround to Red Hat 7.0's broken gcc. + * Added Sparc Solaris kernel panic to `bsod'. + +3.27 * New hacks: `zoom' and `whirlwindwarp'. + * Fixed a free-memory-reference bug in `sonar'. + * Better error handling when there are no suitable GL visuals. + * Added diagnostic dialog when xscreensaver-demo is unable to launch + xscreensaver (e.g., when running as root.) + * Fixed a bug that caused screenhack argument changes to be ignored + when xscreensaver-demo was running as root (if "root" and "nobody" + have different home directories.) + * Made the programs default to ":0" if $DISPLAY is unset. + * Made the `-verbose' output include information about which server + extensions were supported at compile time. + * Worked around Red Hat 7.0's broken gcc 2.96. + * Updated default delays on the GL hacks to look better on machines + with super-fast 3D hardware. + * Install `screensaver-properties-capplet' to work around the usual + egregious GNOME lossage. + +3.26 * Added "enabled" checkboxes in the list of hacks in xscreensaver-demo + (Gtk version only.) + * New hacks `hyperball', `xrayswarm', and `gflux'. + * New versions of `nerverot', `galaxy', and `hypercube'. + * Small fixes to `phosphor', `shadebobs', `xflame', and `sonar'. + * Added external helper program `xscreensaver-gl-helper' to figure out + which X visual to use for OpenGL programs. + * Configure updates for XFree86 4.0, and for BSD. + * Made it be more tolerant of bogus /etc/group files. + * When installing the PAM config file, first try to just copy an + existing "xdm" or "login" config file, so that xscreensaver does + authentication in the same way as the rest of the system. + +3.25 * New hack, `nerverot'. + * Added BSD kernel panic to `bsod'. + * New version of `shadebobs'. + * New version of `petri'. + * Updated `webcollage' to handle recent Altavista URL format changes; + made it search the AP photo gallery. + * Revamped command-line options of `sonar' and made it properly handle + subnets. + * The `bubbles' hack can now trickle up or down the screen. + * The `xsublim' hack can now read its text from programs. + * Support for GLE version 3 in `extrusion'. + * Fixed compilation problems in `maze'. + * Fixed a rare crash in `flow'. + * Fixes for minor installation problems. + +3.24 * Added `-ignorant' option to `maze' hack. + * Updates to `critical', `bsod', `xflame', and `flow'. + * Added support for Kerberos 5 (via its Kerberos 4 compatibility + layer.) + * Fixed a bad leak in `xteevee'. + * Updated `webcollage' to handle recent Altavista URL format changes. + * Removed xscreensaver-demo's `Ok' and `Cancel' buttons, since they + were confusing people: all changes are now instantanious. + * Made xscreensaver-demo install itself into the Gnome Control Center. + +3.23 * Fixed some misplaced text fields in the Motif version of + xscreensaver-demo; fixed a crash in the Gtk version that would + happen if the programs list was empty. + * Fixed a recently-introduced bug in `pulsar'. + * Made `sierpinski3d' use solid tetrahedrons instead of points. + * Added `-trace' option to `xmatrix'. + * Added new hacks `xteevee' and `xspirograph'. + +3.22 * Fixed some bugs in xscreensaver-demo. + * Rewrote the Motif version of xscreensaver-demo to match the new Gtk + version. + * The Athena toolkit is no longer supported. + +3.21 * Tweaked the xscreensaver-demo UI (Gtk only.) + * Fixed a few visual selection bugs. I think the proper GL visual + should be used with nVidia systems now. + * Made the Makefiles obey $install_prefix. + * Made the `xscreensaver.spec' file able to generate both GL and + non-GL packages simultaneously. + +3.20 * Added new hacks `ripples' and `sierpinski3d'. + * Made `xscreensaver-command -exit' be silent when no screen saver was + running (instead of complaining.) + * Made `webcollage' and `vidwhacker' use `xloadimage' when available + (in addition to `xli' and `xv'.) + * Improved memory usage in `petri' and gave it a hard cap on how much + memory it can allocate. + * Added `-watch' option to `xscreensaver-command'. + * Made `xscreensaver-demo' come up with the most-recently-run hack + selected by default. + * Rewrote the Gtk version of `xscreensaver-demo'. It's a lot easier + to use now. + * Extended the format of the programs list in the .xscreensaver file, + for the benefit of the new capabilities of `xscreensaver-demo'. + NOTE: you might want to delete your ~/.xscreensaver file and allow + it to be re-created! The old one should still work, but + xscreensaver-demo won't be as pretty. + +3.19 * Fixed gcc dependencies in `bumps' and `ccurve'. + * New hack, `extrusion'. + * Some of the web sites that `webcollage' was using as its sources + changed formats; tweaked it to understand the current layouts. + * Added typeahead in the password dialog: if the screen is locked, and + you unlock it by typing a character, that key will be automatically + inserted in the password dialog (unless it is Return, Enter, Space, + or a non-printing key like Shift.) + * Made `xmatrix' take a `-small' option, since some folks with tiny + screens prefer a smaller font. + +3.18 * New versions of `shadebobs', `lmorph', and `distort'. + * Added `ccurve', `blaster', and `bumps' hacks. + * Replaced `forest' hack with a rewritten version. + * Worked around a Xinerama server bug. + * Fixed a bug I introduced in 3.10 that caused some hacks to print out + superfluous warnings about not having gotten enough colors. + * Made `sproingies' obey the `-delay' option. + * Fixed a portability bug in `shadebobs'. + * Made `webcollage' and `vidwhacker' use `xli' in preference to `xv', + if it is available. + * Added a new source of images to `webcollage'. + * If running under KDE, xscreensaver will add itself to KDE's list of + screensavers (via xscreensaver.kss.) + * Improved detection of GL libraries. + * Made the password dialog include the date and time. + +3.17 * New version of `webcollage' -- deals better with corrupted images, + and can use an http proxy. + * New hack, `xsublim' (run it in the background, rather than adding it + to the programs list.) + * The xscreensaver daemon was leaking a file descriptor each time you + edited your .xscreensaver file. Fixed. + +3.16 * New version of `shadebobs'. + * Improved image selection in `webcollage', and sped it up slightly. + * Made configure find the right version of perl. + * Rewrote the CGI part of `webcollage'. + * `make clean' was deleting some things it shouldn't. + * Fixed a typo in the default programs list. + +3.15 * Added `webcollage' and `shadebobs' hacks. + * Added a `-stdout' arg to `vidwhacker' so that it can be used in a + pipeline. + * Made `petri' use less memory. + +3.14 * Various improvements to the Gtk port. + * Turned off PAM by default on Solaris, since PAM seems generally to + be misconfigured out-of-the-box. + * Made the `--without-gtk' configure option work. + * Made configure check the Gtk version number, since it requires 1.2. + * Fixed a bug in the code that attempted to prevent changes of screen + resolution while the screen is locked. + * Fixed a race condition in `xscreensaver-demo' that could cause an X + error at startup. + * Added `-transparent' option to `deluxe'. + * Added `petri' hack. + +3.13 * Ported `xscreensaver-demo' to Gtk. + * Made it possible to build Motif, Gtk, and Athena versions of + `xscreensaver-demo' in the same directory without reconfiguring. + * Made `xscreensaver-demo' chase symlinks before writing the + .xscreensaver file, so that if .xscreensaver is itself a symlink, + the underlying file will be replaced instead. + * Some Makefile and configure tweaks for Solaris and FreeBSD. + * Made it possible to set the fire color in `xflame'. + * Made transparency work in TrueColor (for `goop' and `qix'.) + * Fixed a multi-head bug introduced by the virtual viewports stuff. + + +3.12 * Made it so that you can't scroll the screen while the lock dialog is + up (with XFree86 virtual viewports.) + * Fixed a bug in `flag' that caused bob's chin to get cut off after a + few iterations. + +3.11 * Made `xjack' be black-on-white-ish, so that it looks less like a + computer screen and more like the typewritten paper it's supposed to + be. + * New version of `pulsar'. + * Fixed Solaris compilation problem in `phosphor'. + * Made xscreensaver notice XFree86's virtual root window hack, so that + if the X server's root window is larger than the monitor's + displayable resolution, the screen saver will limit itself to the + area that actually appears on the screen. + * Made the xscreensaver daemon do a better job of picking the visual + class that should be used for GL programs. Less user intervention + should be needed now: you can use the logical visual name `GL' + instead of having to figure out by hand which one to use. + * Oops, the visual was defaulting to "best" instead of + "default", because the .xscreensaver file was not being + loaded quite early enough. + * Made configure figure out how to build icmp ping support into the + `sonar' hack automatically. + * Made warnings about not being able to read shadow passwords not be + printed if compiled with PAM support. + * Improved PAM startup diagnostics. + * Worked around the Solaris PAM bug that was causing crashes there, so + now PAM is turned on by default. + * Made configure detect the number of arguments that pam_strerror() + takes, since on Linux, this apparently changed between 2.0 and 2.2, + sigh. + * Made the /proc/interrupts kludge look for "PS/2 Mouse" as well as + "keyboard". + * Made xscreensaver notice when there has been a sudden large jump in + wall-clock time, and if so, lock right away, instead of waiting for + "lockTimeout" to expire first. (Laptops need this for safer + recovery from ``hibernation.'') + * Added `-throttle' option to `xscreensaver-command'. + +3.10 * Added `phosphor', `xmatrix', and `pulsar' hacks. + * Fixed a bug in the color allocator that sometimes caused `starfish' + to fall back to monochrome. + * Reduced the amount of code that runs before root privileges are + disavowed: "normal" and "shadow" passwords now do some + initialization as root, but the PAM and Kerberos authorization + schemes will be initialized while running as "nobody". Supposedly + this closes a potential security hole when using Kerberos. + * Added some more sanity checking to configure. + +3.09 * Added `compass', `squiral', `xflame', `wander', `spotlight', and + `critical' hacks. + * Added some new modes to `decayscreen'. + * Made `deluxe' work in monochrome. + * Generalized usage of the Double-Buffer server extension in several + hacks (`compass', `deluxe', `interference', `kumppa', and `moire2'.) + * Fixed another visual-depth problem in `rd-bomb'. + * The screen saver will now defer blanking if neither the keyboard nor + the mouse could be grabbed. Instead, it will just try again in a + few minutes. This fixes a bad interaction between xscreensaver and + programs like VMware that hold the mouse and keyboard grabbed for a + long time. + * Added a new erase mode (expanding spiral.) + +3.08 * Fixed some bugs in my port of `t3d'. + * Added `penetrate' and `deluxe' hacks. + * When linking against Motif 2.x, also link against XPM. + * Added support for using /proc/interrupts for idle detection on + Linux. Now xscreensaver shouldn't kick in when the user is active + on a non-X virtual console. + * Upgraded to autoconf 2.13. + +3.07 * Configure tweaks (sometimes -lXmu wasn't getting linked in properly; + check for _Xsetlocale in -lXintl.) + * Portability fixes for sonar.c. + * Fixed a compilation problem when you have GL but don't have XPM. + * Made configure notice when MesaGL requires -lpthread. + * Made `flame' ignore SIGFPE (not sure if this is the right fix; it + seems only to be needed on FreeBSD.) + * Kludged `rd-bomb' work on visuals that are of depth 24 but that *do + not* support pixmaps of depth 32. + * Fixed `halo' to work properly in TrueColor. + * Changed `xscreensaver.spec' to install the hacks in + /usr/X11R6/lib/xscreensaver/ by default, since that's where recent + Red Hat distributions put them. + * Added `t3d' hack. + * Updated versions of `crystal', `hopalong', and `flow' from + xlockmore. + * Imported `demon' and `loop' modes from xlockmore. + +3.06 * Oops, the "default-n" visual descriptor was broken; it was always + installing a colormap if the `installColormap' preference was set, + meaning that `xearth', `xv' and friends were using the wrong colors + on 8-bit systems. + * Turned off HAVE_PING in `sonar', since it compiles on some Linux + systems, but not others of similar vintage... + +3.05 * Fixed an off-by-1 in `distort'. + * Added `sonar' hack. + * New version of `glplanet' (with stars.) + * Made all hacks exit when you type `q' or `ESC' at them, and made + them obey the WM_DELETE_WINDOW ClientMessage. + * Fixed a nonfatal buffer overrun in lament (note: lament still + doesn't work with MesaGL 3.0: it dies in + lambda_textured_triangle1(), which is Mesa's bug, not mine.) + +3.04 * Added an `xscreensaver.spec' file, to make it easier for other folks + to generate RPMs. + * Made the password code work on HPUX in the situation where: + ``enhanced security'' is available; but not used; but the user typed + a password more than 8 characters long anyway. FTSOHPUX. + +3.03 * Made locking work when passwd aging is enabled. + * Added support for PAM (Pluggable Authentication Modules.) It is + still turned off by default, though, since it doesn't seem to work + on Solaris 2.6, and has been behaving erratically on Red Hat 5.1. + * Made each possible authentication method be tried in turn until one + succeeds; this means that Kerberos is being used, we will first + check Kerberos, and if that fails, will then consult the local + password file. Likewise with PAM. + * Save and restore the bits under the passwd dialog, to avoid leaving + a black rectangle behind when unlocking is cancelled. + +3.02 * Not everyone has sys/select.h, sigh... + +3.01 * Some fixes to `reflect'. + * Configure tweaks. + * Made it log unsuccessful attempts to unlock the screen to syslog. + * Fixed a bug where `xscreensaver-demo' could be seeing a different + programs list than `xscreensaver' did. + +3.00 * The xscreensaver daemon no longer links against Motif or Athena: + demo-mode and the preferences panel are no longer built in to the + daemon, but are now handled by an external program, + `xscreensaver-demo'. (I decided that this, along with the recent + addition of the `.xscreensaver' config file, justified bumping the + version number to 3.00, since this is a fairly major architectural + change.) + * Lines in the `*programs' resource may now begin with the character + "-", meaning "don't run this hack." In this way, it's possible to + disable a hack without throwing away the information about it + (making it easier to change your mind later.) Eventually the + preferences/demo mode GUI should represent this as a checkbox or + something. + * Fixed a short race condition where it was possible for xscreensaver + to die with a BadWindow error if it was blanking the screen just as + another window was being deleted. + * Made it possible to disable specific modes in `bsod'. + +2.34 * Fixed a bug that was making `pipes' generate way too many valves. + Made the viewpoint in `pipes' be selected randomly instead of always + being -10 degrees. + * Fixed a bug in the XSHM code, in the case where the server supports + the XSHM extension but is not the same machine as the client. + * Made `rd-bomb' default to taking up the whole screen. + * Made it not try to do fading/unfading if no PseudoColor visuals + exist. + * Initial attempt at supporting VT-locking (doesn't work yet.) + * Eliminated the `captureStdout' resource; now `captureStderr' + controls both streams. + * Added `-capture-stderr' and `-no-capture-stderr' command-line + arguments. + * Added `glplanet' hack. + * When a hack is selected with `xscreensaver-command -select', that + hack will be used until further notice (until the saver turns off, + or another activation command is issued.) + +2.33 * Made `xscreensaver-command' print error messages: the xscreensaver + daemon now responds to ClientMessage events by writing a response + message on a window property, instead of just writing to its stderr. + * Made the ~/.xscreensaver file be automatically reloaded when the + file date changes. + * The password dialog and splash screen no longer depend on Motif or + Athena. This should clear up a number of focus problems, and is the + first step on the path toward moving all of the + Motif/Athena/whatever code out of the xscreensaver daemon, and into + external processes. + * Don't complain about LessTif 0.86 any more, since the new password + dialog makes that problem go away. + * Configure tweaks for Irix 6.5, SunOS 5.something. + * New `-reflect' option to `distort'. + +2.32 * Added reading and writing of a ~/.xscreensaver file, so that the + Preferences panel can save its settings. + * New version of `rubik'. + * Added `-select N' argument to `xscreensaver-command'. + * Oops, left out some of the `bubbles3d' files... + +2.31 * The cursor was invisible in the password dialog. Fixed. + * Made configure warn against MesaGL 2.6. + * Fixed X error at startup when using non-default visual. + * New version of `crystal', `ant', and `atlantis' from xlockmore. + * New hack, `bubble3d'. + * Added some new modes to `bsod'. + +2.30 * Changed the order in which -lSM and -lICE are linked to be after + Motif instead of before (Lesstif on Irix needs this.) + +2.29 * Work around a bash bug in configure. + * Tweaked HPUX paths again. FTSOHPUX. + * Made configure recommend against LessTif 0.86, due to a bug in that + version that causes a security hole in the screen locking code. + LessTif 0.87 will fix it. + * Made all of the `--with' options to `configure' accept a directory + option as well (so that --with-motif=/FOO will add -I/FOO/include + -L/FOO/lib). I believe this is the Configure Party Line of how do + to such things. + * Fixed a bug where the mouse was left un-grabbed after the first time + the graphics hack was changed (simplified all of the mouse-grabbing + logic.) + * Maybe possibly perhaps made `vidwhacker' really not leave stray xv + windows around. This time for sure. + * Added a new erase mode (random dots fizzling out.) + * Added `-prefs' argument to `xscreensaver-command', that brings up + the Preferences dialog directly (it seems that nobody ever noticed + the `Preferences' button on the Demo Mode dialog, maybe this will + help.) + * Added a splash screen. Turn it off with *splash:false. + +2.28 * Better macsbug text in `bsod'. + * New version of `distort' with many new modes. + * Plugged a leak in `coral'. + * Tweaked configure for HPUX. + * Removed some compiler warnings. + * More consistent usage of stderr versus stdout. + * More diagnostics should an X error occur. + * Fixed a possible crash in SGI-specific unfading code. + +2.27 * Improved version of `distort'. + * Made `lament' compile against OpenGL 1.0 (though it still requires + 1.1 to work properly.) + * Updated my email address and home page. + +2.25 * Improved motion in `rd-bomb'. + * Added XSHM (shared memory extension) support to the `distort', + `interference', `moire', `rd-bomb', and `swirl' hacks, which speeds + them up a bit. + * Added `lament' hack. + +2.24 * Tweaked the order of the -L options again. + * Cleaned up configure's `--help' message. + * Added `kumppa' hack. + * Smarter maze-solving algorithm in `maze'. + * Took `xlyap' out of the default list of hacks, since it's just + incredibly buggy (and slow.) Maybe someday someone will fix it... + * Added `distort' hack, but didn't add it to the default list (yet) + because it's still too slow. + * Made the Athena demo dialog look more like the Motif version; it has + a text-entry field now, too. + * Made the Athena password dialog echo asterisks, like Motif does, + instead of using a flyspeck font. + * Some random configure tweaks. + * Added a `timestamp' resource that makes the `-verbose' messages + include the time at which they were printed. + +2.23 * The fix for SGI's ``scheme'' nonsense broke things, and let the + user's "*background" resource show through. Fixed it in a different + way. + +2.22 * Added support for the DPMS server extension (Display Power + Management System.) + * Made configure advertize the `--enable-subdir' option a little more, + since that seemed to cause some people stress. Also, made that + directory be built into the xscreensaver executable, as a hardcoded + prefix to $PATH. (Might help, shouldn't hurt.) + * Made configure prefer the two-arg gettimeofday to the one-arg + version, since AIX doesn't have any prototypes. + * Made it work with Xaw3d (the 3D Athena library.) + * Made `make install' create directories as necessary. + * New version of lmorph from Sverre. + * Added `crystal' and `discreet' hacks from xlockmore. + * Added a new mode to `bsod'. + +2.21 * Made `xscreensaver-command -time' use different words. (It now + describes the two states as "screen blanked since..." and "screen + non-blanked since..." instead of "active since..." and "inactive + since..." which a lot of people interpreted as meaning the opposite + of what was intended.) + * Improved some error messages, in the hopes of making the distinction + between the xscreensaver and xscreensaver-command programs more + obvious. + * Rewrote (and reorganized) parts of the xscreensaver and + xscreensaver-command manual pages. + * Renamed xscreensaver's `-lock' command-line option to be + `-lock-mode', to avoid confusion with the `-lock' option to + xscreensaver-command, which does a totally different thing. + * Removed xscreensaver's `-demo' command-line option for a similar + reason; use `xscreensaver-command -demo' instead. + * Disabled SGI's ``scheme'' nonsense in a better way than + fully-qualifying the background colors in every single hack. + * Fixed some other minor cosmetic problems when *sgiMode is turned on. + * Fixed an X error in `bsod -root' (how ironic...) + +2.20 * Fixed a bug that caused the mouse to sometimes not be grabbed + properly (meaning the window manager menu could pop up over the + demo-mode display.) + * Fixed a bug that made the stderr output sometimes get printed twice. + * Fixed a bug that made the demo-mode scrollbar move too fast. + * Protected against a possible buffer overflow. + * Made `vidwhacker' not leave stray xv windows around. + * New version of `ant' so that Bagley doesn't calve. + * Make configure on AIX get XShm from the right library. + +2.19 * One file was missing from the tar file. + +2.18 * Oops, atlantis wasn't being built by default. + * Added `epicycle' hack. + * Added `interference' hack. + * Added `truchet' hack. + * Added `bsod' hack. + * Added some new modes to `vidwhacker'. + +2.17 * Added a -window-id argument to most hacks, so that they can draw on + arbitrary externally-provided windows. + * Synched with xlockmore 4.11a01. + * Added `flow' hack. + * Added `atlantis' GL hack. + * Renamed `puzzle' hack to `jigsaw', since xlock already had a + different mode called `puzzle'. + * Made it self-configure properly when Motif 2.1.0 is being used + (requires -lXp now, sigh...) + +2.16 * Made `flag' able to do XPM images. + * New look for the xscreensaver logo (`xroger'). + * Fixed compilation error on Suns with adjunct passwords. + * Got multi-architecture builds working again. + * Some configure tweaks for building on HPUX and Solaris. + * Fixed bug in decayscreen. + * Fixed typo in passwd.c. + * Made `cynosure' not die when colormap is full. + +2.15 * Added `cynosure' hack. + * Added `moire2' hack. + * Tweaked `erase.c' some more. + * Made unfading a bit smoother. + * Added `vidwhacker' hack (not installed by default.) + * Added `stairs' hack. + * Split `escher' into `cage' and `moebius', as per xlockmore. + * Changed subprocess handling to use sigaction() instead of signal() + if it's available (this is necessary for SCO but should work fine on + other systems too.) + * Various other tweaks. + +2.14 * Better fix for the Motif drag-and-die lossage. + * Put in some kludges to work around a LessTif bug. + * XScreenSaver is known to work with LessTif 0.82 now. + * Made fading work on high-end SGI video hardware. + * Fixed another SGI-specific bug in screen grabbing; will the madness + never cease? + * Fixed another crash in `xlyap'. + +2.13 * Made `decayscreen' do directions other than down. + * Improved `puzzle'. + * Fixed a crash in `xlyap'. + * Added CDE info to the man page, removed `cde.txt'. + * Configure tweaks for Zippy. + * Turned off the signal handling in `bubbles' because it was sometimes + failing to die. + * Added `hacks/xscreensaver-sgigl.c' to make it possible to run SGI's + ElectroPaint hack (/usr/demos/bin/ep) with xscreensaver. Finally! + * Fixed a buffer overrun in the locking code that some wily, malicious + cracker must have slipped in. + * Disabled Motif drag-and-drool in the dialog box buttons, since it's + broken in some old versions of Motif. + +2.12 * Added `README.debugging'. + * Added `puzzle' hack. + * Added `xlyap' hack. + * Added `default-n' as a visual name, so that one can have -install on + by default, but turn it off for certain poorly-behaved hacks (like + xv.) + * Added support for grabbing frames of external video (on SGI) to the + screen-grabbing hacks (decayscreen, slidescreen, slip, blitspin, and + puzzle.) + * Improved look of tiles in `slidescreen'; fixed its color allocation + problem. + +2.11 * Tweaked `blitspin', added it to the default list. + * Added `lissie', `mountain', `triangle', `worm', `rotor', and `ant' + from xlockmore. + * Updated `sierpinski', `galaxy', and `lisa'. + * Thickened the lines in `braid' and `lmorph'. + * Updated VMS makefiles. + * Renamed `fract' to `vines'. + * Added `xjack' hack. + * Made a few more hacks use erase.c, and added a few more wipe styles. + * Fixed compilation problem with Sun's version of OpenGL. + * Added ability to use sigaction() instead of signal() + to work around a SCO kernel bug. + +2.10 * Fixed colormap bugs in `rd-bomb'; sped up `coral'. + * Configure tweaks for *BSD. + +2.08 * New hacks `rd-bomb' and `coral'. + * New version of `maze' with some new algorithms. + * New colorized version of `rocks'. + * Fixed a bug in qix on 64-bit machines. + * Fixed a bug in the -time option. + * Fixed a bug in configure related to LessTif. + +2.07 * Minor header tweaks in windows.c and flag.c. + * Made multi-architecture ($VPATH) builds work properly. + * Merged new GL stuff from xlockmore (rubik, morph3d.) + * Fixed intermittent crashes in `imsmap' and `munch'. + * Added `fadeplot' hack from xlockmore. + +2.06 * Merged in VMS support from Patrick Moreau. + +2.05 * Fixed a MIT-SCREEN-SAVER-related crash, and tweaked + configure to detect the extra-random -Xss library. + +2.04 * HP configure tweaks. Detect and warn about LessTif. + * Fixed low-color behavior of `goop', `pyro', `starfish', + `greynetic', `flame', `halo', and `moire'. + +2.03 * Fixed flicker in `pipes'. Fixed 3d in `bouboule'. + * Added `munch' hack. + * Added basic dependencies to the Makefile.in files. + +2.02 * Fixes for compiling with the MIT saver extension. + * Made the yow/fortune program be a configure option. + * Various configure tweaks. + +2.01 * Added `goop' and `starfish' hacks. + * Added colomap cycling to `halo'. + * Made `attraction' use the new colormap allocator. + * Added better $PATH diagnostics. + * There was a bug in frand! Color selection should be much improved + now. + +2.00 * Converted to use `configure' instead of `imake'. + * ANSI C is now required. + * Added Kerberos locking support, from Nat Lanza. + * Made the stderr text use overlay planes, if possible. + * Reworked the xlockmore compatibility stuff again. + * Added `gears', `superquadrics', `escher', `pipes', and `sproingies' + hacks (depend on OpenGL.) + +1.34 * Fixed some bugs, made fading be a little smoother. + +1.33 * Made it work with multi-headed displays. + * Generalized sub-process management (Unix sucks!) + * Added interactive mouse frobbing to Julia. + * Added (untested) support for HPUX shadow passwords. + * Made normal non-shadow passwords be checked if the shadow passwords + aren't accessible for some reason. + +1.32 * Removed *colorPrograms and *monoPrograms resources: made it possible + to specify the desired visual on a per-hack basis. + * Cleaned up / restructured the driver: no more globals. + * Made the Motif and Athena dialogs share more code. + * Probably fixed some Athena colormap-installation bugs. + * Fixed screen grabbing (cmap) on SGI 12-bit PseudoColor. + * Fixed divide-by-zero in bright random colormaps. + * Added an improved version of xlock's `flag' hack. + * Made unfading work better, and not flicker on SGIs. + * Added `sphere', `forest', `lisa' hacks from xlockmore. + * Added (untested) support for SunOS Adjunct passwords. + +1.31 * Improved colors and colormap cycling of many hacks. + * Cleaned up xlockmore compatibility layer. + * Made `blitspin' able to grab an image off the screen. + * Ported `swirl' and `bouboule' hacks from xlockmore. + * Made the driver more careful about not leaving bits on the screen, + or allowing other windows to raise themselves: it now re-blanks the + screen every so often. + * Added `-time' option to `xscreensaver-command'. + * Improved SGI screen-grabbing some more: now it can grab TrueColor + screens into PseudoColor windows and have the colors still come out + semi-reasonably. + +1.30 * Made `slidescreen' and `decayscreen' work better on SGIs when + windows of different visuals are present, by using the + XReadDisplay() extension to get a true 24-bit image out of the frame + buffer. + * Made `noseguy' be in color, if compiled with XPM. + * Ported `braid', `drift', `fract', `galaxy', `grav', `ifs', `julia', + `laser', `lightning', `penrose', `sierpinski', `slip', `spiral', and + `strange' hacks from xlockmore. + * Merged `hopalong' hack with a more recent version. + * Added `cde.txt'. + +1.28 * Added `deco', `moire', and `kaleidescope' hacks. + * Merged in support for non-Motif locking and demo mode. + * Made `blitspin' and `bubbles' work in TrueColor. + * Fixed a stupid bug I introduced in `imsmap'. + * Added `poly' and `gravity' options to `qix'. + +1.27 * Added support for SGI SCREEN_SAVER extension. + * Made `fade' and `unfade' work on 8-bit SGIs. + * Made the dialog boxes more Motify. + * Added `bubbles' hack. + +1.26 * Added `lmorph' hack. + * Added viscosity and mouse-control to attraction. + * Fixed possible bad color choices in qix and attraction. + * Added ramp-mode to halo. + * Added a new RNG, which is faster and more portable than using the + RNG in libc. + * Made locking work on SCO. + * Various other minor tweaks that I don't remember. + +1.25 * Made it capture the stdout/stderr of its subprocesses and present + them on the screensaver window itself. + * Made demo mode work correctly with non-default visuals and color + maps, instead of always using the defaults. + * Added -visual argument to all included screenhacks. + * Support for the R6 MIT-SCREEN-SAVER server extension. + * Made the demo mode list scroll properly. + * Added `pedal' hack. + +1.24 * Fixed some private-colormap oddities in slidescreen, decayscreen, + and xroger. Fixed apparent conservation- of-mass problem in pyro; + made the shrapnel round. + +1.23 * Minor tweaks for IRIX5; fixed locking race condition. + +1.22 * Minor tweaks for X11R6. + * Fixes for non-default visuals. + +1.21 * Fixed bug in color blitspin; added default image. + * Added diagnostics to noseguy. Fixed off-by-one error in flame. + * Added some missing casts. + +1.19 * Added `flame' hack. + * Fixed a minor Motif dialog text field bug. + * Fixed yet another XPointer-not-defined-in-R4 bug. + +1.18 * Added support for shadow password files. + * Fixed some Motif-related locking bugs. + * Added diagnostics when locking is disabled. + * Made blitspin able to use the XPM library. + * Added `decayscreen' hack. + +1.17 * Added `halo' hack. + +1.16 * Portability fixes. + +1.15 * Broke the driver up into more source files. + * Moved the hacks into their own directory. + * Made all `time' parameters accept the 00:00:00 syntax, so that even + the parameters which are normally read as minutes can be specified + in seconds. + * Added colormap cycling to `imsmap'. + * Made hyper work with K&R compilers. + +1.14 * Added `orbit' option to `attraction' hack. + * Added `lock-timeout' option. + * Cleaned up options of `maze' hack. + +1.09 * Added demo mode, and locking. + * Added `maze' hack. + * Added `norotate' option to `rocks' hack. + +1.05 * Works when run from XDM before anyone logs in. + * Sped up `imsmap'. + * Can use `xv' as a slideshow without using up colormap entries while + the screen is not blanked. + * Fixed a BadDrawable error in non-XIdle mode. + * Added `blitspin' and `imsmap'. + +1.01 * Current list of included hacks is now: qix, helix, rorschach, + attraction, greynetic, rocks, pyro, hopalong, and noseguy. diff --git a/README.VMS b/README.VMS new file mode 100644 index 00000000..d1903443 --- /dev/null +++ b/README.VMS @@ -0,0 +1,57 @@ +OpenVMS port of Xscreensavser version 2.10 October 1997 +========================================== + +Xscreensaver distribution can be found in 3 subdirectories: + +[.DRIVER] The Xscreensaver and Xscreensaver-command programs. +[.HACKS] Graphic demos ,can be run either through the xscreensaver program + or standalone. +[.UTILS] A small libraries of various utilities. + +This port has been tested with VAX VMS 6.1 (compiled with DEC 5 5.0 and +Motif 1.2) and AXP VMS 6.2 (compiled with DEC C 5.0 and Motif 1.2-4). + +To rebuild, you need to rebuild [.UTILS] directory first and create the +object library (look at the end of COMPILE*.COM procedure). + +You can now build the [.HACKS] directory and the [.DRIVER] directory. + +A one-step build is now available via the MAKEVMS.COM script. + +WARNING : before building [.HACKS], you may need to correct some of the +DECwindows bitmap files. Some files are bogus !! (they have a long line of +null chars at the end). These files are under +SYS$COMMON:[DECW$INCLUDE.BITMAPS] directory: + +STIPPLE.XBM +HLINES2.XBM +LIGHT_GRAY.XBM +ROOT_WEAVES.XBM +VLINES2.XBM + +These files are all used by Greynetic demo. + +Nota: link procedure automagically select appropriate X and Motif Libraries +(X11R4/Motif 1.1 - X11R5/Motif 1.2). + +The SETUP.COM procedure gives you a definition of all DCL foreign command +symbols needed to run Xscreensaver and all the graphic hacks. You need to +modify this procedure if you install these programs in another directory tree. + +You can easily add new graphic demos without recompiling Xscreensaver. You just +need to add them in resource file XSCREENSAVER.DAT. This file (originally +present in [.DRIVER] directory ) can be installed under your SYS$LOGIN +directory for a per-user customization basis. You can also install it under +the system-wide user resource directory SYS$COMMON:[DECW$DEFAULT.USER] +(with (W:RE) protections). The new graphics hack must be run in root-window +mode to be accepted by Xscreensaver. + +The graphic demos are spawn into subprocess created by the system() call (in +the Unix version the execvp() call is used). + +The VMS passord checking programs were picked up in the Xlock distribution. + +Enjoy, + +Patrick MOREAU - CENA/Athis-Mons - FRANCE (pmoreau@cena.dgac.fr) + (moreau_p@decus.decus.fr) diff --git a/README.hacking b/README.hacking new file mode 100644 index 00000000..718cae2b --- /dev/null +++ b/README.hacking @@ -0,0 +1,180 @@ + +========================================================================== + + Writing new XScreenSaver modules + +========================================================================== + +Any program that can be made to render on an X window created by another +process can be used as a screen saver. Just get the window ID out of +$XSCREENSAVER_WINDOW, draw on that, and you're done. + +In theory, you can write a screen saver in any language you like. In +practice, however, languages other than C or C++ tend not to allow you to +draw to windows that they did not create themselves. Unfortunately, this +means that if you want to write a screen saver, you must write it in C. + +Given that you're going to be writing in C, you might as well take +advantage of the various utility functions that I have written to make +that easier. Writing a new screen saver in C using the frameworks +included with xscreensaver simplifies things enormously. + +Generally, the best way to learn how to do something is to find a similar +program, and play around with it until you understand it. Another +approach is to not worry about understanding it, but to just hack it out. +Either way, your best bet is probably to start with one of the existing +xscreensaver demos, included in the "hacks/" directory, rename the file, +and edit it until it does what you want. + +The "Greynetic" and "Deluxe" hacks are probably good ones to start with, +since they are so very simple. For OpenGL programs, "DangerBall" is a +good example. + + +========================================================================== +Requirements for inclusion with the XScreenSaver collection +========================================================================== + + If you come up with anything, send it to me! If it's good, I'd love to + include it in the xscreensaver distribution. However, there are a few + requirements for me to distribute it: + + - Write in portable ANSI C. No C++. No nonstandard libraries. + + - Write a .man page describing all command-line options. + + - Write an .xml file describing the graphical configuration dialog box. + + - Include a BSD-like copyright/license notice at the top of each source + file (preferably, just use the one from "screenhack.h", and include + your name and the current year). The GNU GPL is not compatible with + the rest of XScreenSaver. + + +========================================================================== +The XScreenSaver API +========================================================================== + + - Start with #include "screenhack.h" + + - Define 2 global variables: + + yoursavername_defaults -- Default values for the resources you use. + yoursavername_options -- The command-line options you accept. + + - Define 5 functions: + + yoursavername_init -- Return an object holding your global state. + yoursavername_draw -- Draw a single frame, quickly. + yoursavername_free -- Free everything you've allocated. + yoursavername_reshape -- Called when the window is resized. + yoursavername_event -- Called when a keyboard or mouse event happens. + + The "event" function will only be called when running in a window + (not as a screen saver). The "reshape" event will be called when the + window size changes, or (as a screen saver) when the display size + changes as a result of a RANDR event (e.g., plugging in a new monitor). + + It's ok for both the "event" and "resize" functions to do nothing. + + - All other functions should be static. + + - The last line of the file should be + XSCREENSAVER_MODULE ("YourSaverName", yoursavername) + + - Finally, edit the Makefile to add a rule for your program. + Just cut-and-paste one of the existing rules. + + Your "draw" must not run for more than a fraction of a second without + returning. This means "don't call usleep()". Everything has to be a + state machine. + + You may not store global state in global variables, or in function-local + static variables. All of your runtime state must be encapsulted in the + "state" object created by your "init" function. If you use global or + static variables, your screen saver will not work properly on MacOS. + + Do not call XSync() or XFlush(). If you think you need to do that, it + probably means that you are you are relying on the speed of the graphics + card for timing, which probably means that your "draw" function is + taking too long. + + +========================================================================== +The XLockMore API +========================================================================== + + Some of the display modes that come with xscreensaver were ported from + XLock, and so, for historical reasons, they follow a slightly different + programming convention. For newly-written Xlib programs, you'd be + better off following the pattern used in hacks like "Deluxe" than in + hacks like "Flag". The XLockMore ones are the ones that begin with + "#ifdef STANDALONE" and #include "xlockmore.h". + + But, all OpenGL screen savers have to follow the XLockMore API. + + The XLockMore API is similar to the XScreenSaver API, in that you define + (roughly) the same set of functions, but the naming conventions are + slightly different. Instead of "hackname_init", it's "init_hackname", + and it should be preceeded with the pseudo-declaration ENTRYPOINT. + + One annoying mis-feature of the XLockMore API is that it *requires* you + to make use of global variables for two things: first, for each of your + command line options; and second, for an array that holds your global + state objects. These are the only exceptions to the "never use global + variables" rule. + + +========================================================================== +Programming Tips +========================================================================== + + - Your screen saver should look reasonable at 20-30 frames per second. + That is, do not assume that your "draw" function will be called more + than 20 times a second. Even if you return a smaller requested delay + than that, you might not get it. Likewise, if your "draw" function + takes longer than 1/20th of a second to run, your screen saver may be + consuming too much CPU. + + - Don't make assumptions about the depth of the display, or whether it + is colormapped. You must allocate all your colors explicitly: do not + assume you can construct an RGB value and use that as a pixel value + directly. Use the utility routines provided by "utils/colors.h" to + simplify color allocation. + + - It is better to eliminate flicker by double-buffering to a Pixmap + than by erasing and re-drawing objects. Do not use drawing tricks + involving XOR. + + - If you use double-buffering, have a resource to turn it off. (MacOS + has double-buffering built in, so you'd be triple-buffering.) + + - Understand the differences between Pixmaps and XImages, and keep in + mind which operations are happening in client memory and which are in + server memory, and which cause latency due to server round-trips. + Sometimes using the Shared Memory extension can be helpful, but + probably not as often as you might think. + + - On modern machines, OpenGL will always run faster than Xlib. It's + also more portable. Consider writing in OpenGL whenever possible. + + +========================================================================== +The MacOS X Port +========================================================================== + + Though XScreenSaver started its life as an X11 program, it also now runs + on MacOS X. If you do your development on an X11 system, and follow the + usual XScreenSaver APIs, you shouldn't need to do anything special for + it to also work on MacOS. + + The preprocessor macro HAVE_COCOA will be defined when being compiled in + a MacOS (Cocoa/Quartz) environment, and will be undefined when compiling + against "real" Xlib. + + To compile on MacOS, use the XCode project included in the source + distribution. You shouldn't need to have X11 installed, and shouldn't + need to run "configure" first. MacOS 10.4.0 and XCode 3.1 or newer are + required. + +========================================================================== diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 00000000..ef93b539 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,443 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + + +dnl AC_PROG_INTLTOOL([MINIMUM-VERSION]) +# serial 1 AC_PROG_INTLTOOL +AC_DEFUN(AC_PROG_INTLTOOL, +[ + +if test -n "$1"; then + AC_MSG_CHECKING(for intltool >= $1) + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ printf "%d", $[1] * 100 + $[2]; }'` + INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { printf $[2]; }' < intltool-update.in` + changequote({{,}}) + INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split(${{2}}, VERSION, "."); printf "%d\n", VERSION[1] * 100 + VERSION[2];}' < intltool-update.in` + changequote([,]) + + if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"; then + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found]) + else + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool $1 or later.]) + exit 1 + fi +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -k -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -o -p' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -o -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + +AC_SUBST(INTLTOOL_DESKTOP_RULE) +AC_SUBST(INTLTOOL_DIRECTORY_RULE) +AC_SUBST(INTLTOOL_KEYS_RULE) +AC_SUBST(INTLTOOL_OAF_RULE) +AC_SUBST(INTLTOOL_PONG_RULE) +AC_SUBST(INTLTOOL_SERVER_RULE) +AC_SUBST(INTLTOOL_SHEET_RULE) +AC_SUBST(INTLTOOL_SOUNDLIST_RULE) +AC_SUBST(INTLTOOL_UI_RULE) +AC_SUBST(INTLTOOL_XML_RULE) +AC_SUBST(INTLTOOL_CAVES_RULE) + +# Use the tools built into the package, not the ones that are installed. + +INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract' +INTLTOOL_MERGE='$(top_builddir)/intltool-merge' +INTLTOOL_UPDATE='$(top_builddir)/intltool-update' + +AC_SUBST(INTLTOOL_EXTRACT) +AC_SUBST(INTLTOOL_MERGE) +AC_SUBST(INTLTOOL_UPDATE) + +AC_PATH_PROG(INTLTOOL_PERL, perl) +if test -z "$INTLTOOL_PERL"; then + AC_MSG_ERROR([perl not found; required for intltool]) +fi +if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then + AC_MSG_ERROR([perl 5.x required for intltool]) +fi + +# Remove file type tags (using []) from po/POTFILES. + +ifdef([AC_DIVERSION_ICMDS],[ + AC_DIVERT_PUSH(AC_DIVERSION_ICMDS) + changequote(,) + mv -f po/POTFILES po/POTFILES.tmp + sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + changequote([,]) + AC_DIVERT_POP() +],[ + ifdef([AC_CONFIG_COMMANDS_PRE],[ + AC_CONFIG_COMMANDS_PRE([ + changequote(,) + mv -f po/POTFILES po/POTFILES.tmp + sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + changequote([,]) + ]) + ]) +]) + +# Manually sed perl in so people don't have to put the intltool scripts in AC_OUTPUT. + +AC_OUTPUT_COMMANDS([ + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-extract.in > intltool-extract.out +if cmp -s intltool-extract intltool-extract.out 2>/dev/null; then + rm -f intltool-extract.out +else + mv -f intltool-extract.out intltool-extract +fi +chmod ugo+x intltool-extract +chmod u+w intltool-extract + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-merge.in > intltool-merge.out +if cmp -s intltool-merge intltool-merge.out 2>/dev/null; then + rm -f intltool-merge.out +else + mv -f intltool-merge.out intltool-merge +fi +chmod ugo+x intltool-merge +chmod u+w intltool-merge + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-update.in > intltool-update.out +if cmp -s intltool-update intltool-update.out 2>/dev/null; then + rm -f intltool-update.out +else + mv -f intltool-update.out intltool-update +fi +chmod ugo+x intltool-update +chmod u+w intltool-update + +], INTLTOOL_PERL=${INTLTOOL_PERL}) + +]) + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. +# +# Modified to never use included libintl. +# Owen Taylor , 12/15/1998 +# +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. +# +# +# If you make changes to this file, you MUST update the copy in +# acinclude.m4. [ aclocal dies on duplicate macros, so if +# we run 'aclocal -I macros/' then we'll run into problems +# once we've installed glib-gettext.m4 :-( ] +# + +# serial 5 + +AC_DEFUN(AM_GLIB_WITH_NLS, + dnl NLS is obligatory + [USE_NLS=yes + AC_SUBST(USE_NLS) + + dnl Figure out what method + nls_cv_force_use_gnu_gettext="no" + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, + [AC_TRY_LINK([#include ], [return (int) dgettext ("","")], + gt_cv_func_dgettext_libc=yes, gt_cv_func_dgettext_libc=no)]) + + if test "$gt_cv_func_dgettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for dgettext in libintl], + gt_cv_func_dgettext_libintl, + [AC_CHECK_LIB(intl, dgettext, + gt_cv_func_dgettext_libintl=yes, + gt_cv_func_dgettext_libintl=no)], + gt_cv_func_dgettext_libintl=no)]) + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + LIBS="$LIBS -lintl"; + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT,1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + + # Added by Martin Baulig 12/15/98 for libc5 systems + if test "$gt_cv_func_dgettext_libc" != "yes" \ + && test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS=-lintl + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + fi + ]) + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" != "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [always defined to indicate that i18n is enabled]) + else + dnl Unset this variable since we use the non-zero value as a flag. + CATOBJEXT= + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + rm -f po/stamp-it po/stamp-it.tmp + > po/stamp-it.tmp + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + mv po/stamp-it.tmp po/stamp-it + esac]) + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(AM_GLIB_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +strdup __argz_count __argz_stringify __argz_next]) + + AM_LC_MESSAGES + AM_GLIB_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + test -d po || mkdir po + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/po/$msgformat-msg.sed > po/po2msg.sed + fi + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= +# +# jwz: fuck this! it puts hardcoded pathnames into the generated Makefiles! +# +# if test -n "$ac_aux_dir"; then +# MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" +# fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + + # jwz: you know what, screw it. Let's just use the version that I + # already computed in configure.in, instead of this version that came + # with the i18n crud, ok? + MKINSTALLDIRS="$INSTALL_DIRS" + + + AC_SUBST(MKINSTALLDIRS) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 2 + +AC_DEFUN([AM_LC_MESSAGES], + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi + fi]) + diff --git a/config.guess b/config.guess new file mode 100644 index 00000000..9afd6762 --- /dev/null +++ b/config.guess @@ -0,0 +1,1568 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-11-29' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h-vms b/config.h-vms new file mode 100644 index 00000000..7a30b196 --- /dev/null +++ b/config.h-vms @@ -0,0 +1,284 @@ +/* This is a config.h file that has been pregenerated (from config.h.in) + * with settings that are correct for VMS. + */ + + + +/* config.h.in --- xscreensaver, Copyright (c) 1998 Jamie Zawinski. + * + * The best way to set these parameters is by running the included `configure' + * script. That examines your system, and generates `config.h' from + * `config.h.in'. + * + * If something goes very wrong, you can edit `config.h' directly, but beware + * that your changes will be lost if you ever run `configure' again. + */ + + +/* ************************************************************************* + CONFIGURING SERVER EXTENSIONS + ************************************************************************* */ + +/* Define this if you have the XReadDisplay extension (I think this is an + SGI-only thing; it's in .) A few of the + screenhacks will take advantage of this if it's available. + */ +#undef HAVE_READ_DISPLAY_EXTENSION + +/* Define this if you have the Iris Video Library (dmedia/vl.h on SGI.) + A few of the screenhacks will take advantage of this if it's available. + */ +#undef HAVE_SGI_VIDEO + +/* Define this if you have the XHPDisableReset function (an HP only thing.) + */ +#undef HAVE_XHPDISABLERESET + +/* First, some background: there are three distinct server extensions which + * are useful to a screen saver program: they are XIDLE, MIT-SCREEN-SAVER, + * and SCREEN_SAVER. + * + * The XIDLE extension resides in .../contrib/extensions/xidle/ on the X11R5 + * contrib tape. This extension lets the client get accurate idle-time + * information from the X server in a potentially more reliable way than by + * simply watching for keyboard and mouse activity. However, the XIDLE + * extension has apparently not been ported to X11R6. + * + * The SCREEN_SAVER extension is found (as far as I know) only in the SGI + * X server, and it exists in all releases since (at least) Irix 5. The + * relevant header file is /usr/include/X11/extensions/XScreenSaver.h. + * + * The similarly-named MIT-SCREEN-SAVER extension came into existence long + * after the SGI SCREEN_SAVER extension was already in use, and resides in + * .../contrib/extensions/screensaver/ on the X11R6 contrib tape. It is + * also found in certain recent X servers built in to NCD X terminals. + * + * The MIT extension does basically the same thing that the XIDLE extension + * does, but there are two things wrong with it: first, because of the way + * the extension was designed, the `fade' option to XScreenSaver will be + * uglier: just before the screen fades out, there will be an unattractive + * flicker to black, because this extension blanks the screen *before* + * telling us that it is time to do so. Second, this extension is known to + * be buggy; on the systems I use, it works, but some people have reported + * X server crashes as a result of using it. XScreenSaver uses this + * extension rather conservatively, because when I tried to use any of its + * more complicated features, I could get it to crash the server at the + * drop of a hat. + * + * In short, the MIT-SCREEN-SAVER extension is a piece of junk. The older + * SGI SCREEN_SAVER extension works great, as does XIDLE. It would be nice + * If those two existed on more systems, that is, would be adopted by the + * X Consortium in favor of their inferior "not-invented-here" entry. + */ + +/* Define this if you have the XIDLE extension installed. If you have the + * XIDLE extension, this is recommended. (You have this extension if the + * file /usr/include/X11/extensions/xidle.h exists.) Turning on this flag + * lets XScreenSaver work better with servers which support this extension; + * but it will still work with servers which do not suport it, so it's a good + * idea to compile in support for it if you can. + */ +#undef HAVE_XIDLE_EXTENSION + +/* Define this if you have the MIT-SCREEN-SAVER extension installed. See the + * caveats about this extension, above. (It's available if the file + * /usr/include/X11/extensions/scrnsaver.h exists.) + */ +#undef HAVE_MIT_SAVER_EXTENSION + +/* Define this if you have the SGI SCREEN_SAVER extension. This is standard + * on Irix systems, and not available elsewhere. + */ +#undef HAVE_SGI_SAVER_EXTENSION + +/* Define this if you have the SGI-VIDEO-CONTROL extension. This is standard + * on Irix systems, and not available elsewhere. + */ +#undef HAVE_SGI_VC_EXTENSION + +/* Define this if you have the XDPMS extension. This is standard on + * sufficiently-recent XFree86 systems, and possibly elsewhere. (It's + * available if the file /usr/include/X11/extensions/dpms.h exists.) + */ +#define HAVE_DPMS_EXTENSION 1 + + +/* ************************************************************************* + CONFIGURING GRAPHICS TOOLKITS + ************************************************************************* */ + +/* Define this if you have Motif. + */ +#define HAVE_MOTIF 1 + +/* Define this if you have the XmComboBox Motif widget (Motif 2.0.) + */ +#undef HAVE_XMCOMBOBOX + +/* Define this if you have the XPM library installed. Some of the demos can + * make use of this if it is available. + */ +#define HAVE_XPM 1 + +/* Define this if you have the Xmu library. This is standard part of X, and + * if your vendor doesn't ship it, you should report that as a bug. + */ +#define HAVE_XMU 1 + +/* Define this if you have OpenGL. Some of the demos require it, so if you + * don't have it, then those particular demos won't be built. (This won't + * affect the screen saver as a whole.) + */ +#undef HAVE_GL + +/* Define this if you have OpenGL, but it's the MesaGL variant. (The + libraries have different names.) (HAVE_GL should be defined too.) + */ +#undef HAVE_MESA_GL + +/* Define this if your version of OpenGL has the glBindTexture() routine. + This is the case for OpenGL 1.1, but not for OpenGL 1.0. + */ +#undef HAVE_GLBINDTEXTURE + +/* Define this if you have the X Shared Memory Extension. + */ +#undef HAVE_XSHM_EXTENSION + + +/* ************************************************************************* + CONFIGURING PASSWORD AUTHENTICATION + ************************************************************************* */ + +/* Define this to remove the option of locking the screen at all. + */ +#undef NO_LOCKING + +/* Define this if you want to use Kerberos authentication to lock/unlock the + * screen instead of your local password. This currently uses Kerberos V4, + * but a V5 server with V4 compatibility will work. WARNING: DO NOT USE AFS + * string-to-key passwords with this option. This option currently *only* + * works with standard Kerberos des_string_to_key. If your password is an + * AFS password and not a kerberos password, it will not authenticate + * properly. See the comments in driver/kpasswd.c for more information if you + * need it. + */ +#undef HAVE_KERBEROS + + +/* Define this if your system uses `shadow' passwords, that is, the passwords + * live in /etc/shadow instead of /etc/passwd, and one reads them with + * getspnam() instead of getpwnam(). (Note that SCO systems do some random + * other thing; others might as well. See the ifdefs in driver/passwd.c if + * you're having trouble related to reading passwords.) + */ +#undef HAVE_SHADOW_PASSWD + +/* Define this if your system is Digital or SCO Unix with so-called ``Enhanced + Security'', that is, the passwords live in /tcb/files/auth// + instead of in /etc/passwd, and one reads them with getprpwnam() instead + of getpwnam(). + */ +#undef HAVE_ENHANCED_PASSWD + +/* Define this if your system is Solaris with ``adjunct'' passwords (this is + the version where one gets at the passwords with getpwanam() instead of + getpwnam().) I haven't tested this one, let me know if it works. + */ +#undef HAVE_ADJUNCT_PASSWD + +/* Define this if you are running HPUX with so-called ``Secure Passwords'' + (if you have /usr/include/hpsecurity.h, you probably have this.) I + haven't tested this one, let me know if it works. + */ +#undef HAVE_HPUX_PASSWD + +/* Define this if you are on a system that supports the VT_LOCKSWITCH and + VT_UNLOCKSWITCH ioctls. If this is defined, then when the screen is + locked, switching to another virtual terminal will also be prevented. + That is, the whole console will be locked, rather than just the VT on + which X is running. + */ +#define HAVE_VT_LOCKSWITCH 1 + + +/* ************************************************************************* + OTHER C ENVIRONMENT JUNK + ************************************************************************* */ + +/* Define this to void* if you're using X11R4 or earlier. */ +#undef XPointer + +/* Define if you have the nice function. */ +#undef HAVE_NICE + +/* Define if you have the setpriority function. */ +#undef HAVE_SETPRIORITY + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `int' if doesn't define. */ +#undef mode_t + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if gettimeofday requires two arguments. */ +#undef GETTIMEOFDAY_TWO_ARGS + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the select function. */ +#undef HAVE_SELECT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getcwd function. */ +#undef HAVE_GETWD + +/* Define if you have the uname function. */ +#undef HAVE_UNAME +#if (__VMS_VER >= 70000000) +# define HAVE_UNAME 1 +#endif + +/* Define if you have the fcntl function. */ +#undef HAVE_FCNTL + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_CRYPT_H + +/* Define to use sigaction() instead of signal() for SIGCHLD-related activity. + This is necessary at least on SCO OpenServer 5, due to a Unix kernel bug. + */ +#undef USE_SIGACTION diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..0a1af872 --- /dev/null +++ b/config.h.in @@ -0,0 +1,503 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + + +/* config.h.in --- xscreensaver, Copyright (c) 1998-2000 Jamie Zawinski. + * + * The best way to set these parameters is by running the included `configure' + * script. That examines your system, and generates `config.h' from + * `config.h.in'. + * + * If something goes very wrong, you can edit `config.h' directly, but beware + * that your changes will be lost if you ever run `configure' again. + */ + + +/* Define this to allow the root password to unlock the screen. */ +#undef ALLOW_ROOT_PASSWD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* always defined to indicate that i18n is enabled */ +#undef ENABLE_NLS + +/* Some screenhacks like to run an external program to generate random pieces + of text; set this to the one you like. Note that this is just the default; + X resources can be used to override it. */ +#undef FORTUNE_PROGRAM + +/* This is the name of the gettext package to use. */ +#undef GETTEXT_PACKAGE + +/* Define this if gettimeofday() takes two arguments. */ +#undef GETTIMEOFDAY_TWO_ARGS + +/* Define this if your system is Solaris with ``adjunct'' passwords (this is + the version where one gets at the passwords with getpwanam() instead of + getpwnam().) I haven't tested this one, let me know if it works. */ +#undef HAVE_ADJUNCT_PASSWD + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARGZ_H + +/* Define this if you have Gnome and want to build support for the + xscreensaver control panel in the Gnome Control Center (gnomecc). (This is + needed only with Gtk 1.x.) */ +#undef HAVE_CRAPPLET + +/* Define this if HAVE_CRAPPLET is defined, and the function + capplet_widget_changes_are_immediate() is available. */ +#undef HAVE_CRAPPLET_IMMEDIATE + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRYPT_H + +/* Define to 1 if you have the `dcgettext' function. */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define this if you have the X Double Buffer Extension. */ +#undef HAVE_DOUBLE_BUFFER_EXTENSION + +/* Define this if you have the XDPMS extension. This is standard on + sufficiently-recent XFree86 systems, and possibly elsewhere. (It's + available if the file /usr/include/X11/extensions/dpms.h exists.) */ +#undef HAVE_DPMS_EXTENSION + +/* Define this if your system is Digital or SCO Unix with so-called ``Enhanced + Security'', that is, the passwords live in /tcb/files/auth// + instead of in /etc/passwd, and one reads them with getprpwnam() instead of + getpwnam(). */ +#undef HAVE_ENHANCED_PASSWD + +/* Define to 1 if you have the `fcntl' function. */ +#undef HAVE_FCNTL + +/* Define this if you have the 'forkpty' function: This allows 'phosphor' and + 'apple2' to run curses-based programs, or be used as terminal windows. */ +#undef HAVE_FORKPTY + +/* Define this if you have the GDK_Pixbuf library installed. Some of the demos + can make use of this if it is available. */ +#undef HAVE_GDK_PIXBUF + +/* Define this if you have the gdk_pixbuf_apply_embedded_orientation function + (gdk-pixbuf 2.12). */ +#undef HAVE_GDK_PIXBUF_APPLY_EMBEDDED_ORIENTATION + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define this if you have the getifaddrs() function. */ +#undef HAVE_GETIFADDRS + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define this if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `getwd' function. */ +#undef HAVE_GETWD + +/* Define this if you have OpenGL. Some of the demos require it, so if you + don't have it, then those particular demos won't be built. (This won't + affect the screen saver as a whole.) */ +#undef HAVE_GL + +/* Define this if your version of OpenGL has the glBindTexture() routine. This + is the case for OpenGL 1.1, but not for OpenGL 1.0. */ +#undef HAVE_GLBINDTEXTURE + +/* Define this if glBitmap exists. */ +#undef HAVE_GLBITMAP + +/* Define this if you have the -lgle and -lmatrix libraries (GL extrusion.) */ +#undef HAVE_GLE + +/* Define this if you have the -lgle from GLE version 3 */ +#undef HAVE_GLE3 + +/* Define this if you have Gtk (any version.) */ +#undef HAVE_GTK + +/* Define this if you have Gtk 2.x. */ +#undef HAVE_GTK2 + +/* Define this if you are running HPUX with so-called ``Secure Passwords'' (if + you have /usr/include/hpsecurity.h, you probably have this.) I haven't + tested this one, let me know if it works. */ +#undef HAVE_HPUX_PASSWD + +/* Define this if you do pings with a `struct icmp' and an `icmp_id' slot. */ +#undef HAVE_ICMP + +/* Define this if you do pings with a `struct icmphdr' and an `un.echo.id' + slot. */ +#undef HAVE_ICMPHDR + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define this if you have the Independent JPEG Group's JPEG library + installed. Some of the demos can make use of this if it is available. */ +#undef HAVE_JPEGLIB + +/* Define this to target the OpenGL ES 1.x API instead of OpenGL 1.3. */ +#undef HAVE_JWZGLES + +/* Define this if you want to use Kerberos authentication to lock/unlock the + screen instead of your local password. This currently uses Kerberos V4, but + a V5 server with V4 compatibility will work. WARNING: DO NOT USE AFS + string-to-key passwords with this option. This option currently *only* + works with standard Kerberos des_string_to_key. If your password is an AFS + password and not a kerberos password, it will not authenticate properly. + See the comments in driver/kpasswd.c for more information if you need it. + */ +#undef HAVE_KERBEROS + +/* Define this if you have Kerberos 5, meaning we need to use the Kerberos 4 + compatibility layer. */ +#undef HAVE_KERBEROS5 + +/* Define if your file defines LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define this if you have OpenGL, but it's the MesaGL variant. (The libraries + have different names.) (HAVE_GL should be defined too.) */ +#undef HAVE_MESA_GL + +/* Define to 1 if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define this if you have Motif. */ +#undef HAVE_MOTIF + +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the `nice' function. */ +#undef HAVE_NICE + +/* Define to 1 if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define this if you have the XML library headers in their old, + non-namespaced location (you lack the gnome-xml/libxml symlink) */ +#undef HAVE_OLD_XML_HEADERS + +/* Define this if you want to use PAM (Pluggable Authentication Modules) to + lock/unlock the screen, instead of standard /etc/passwd authentication. */ +#undef HAVE_PAM + +/* Define this if you have pam_fail_delay function. see driver/passwd-pam.c. + */ +#undef HAVE_PAM_FAIL_DELAY + +/* Define this if you have a Linux-like /proc/interrupts file which can be + examined to determine when keyboard activity has occurred. */ +#undef HAVE_PROC_INTERRUPTS + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTY_H + +/* Define to 1 if you have the `putenv' function. */ +#undef HAVE_PUTENV + +/* Define this if you have the Resize and Rotate extension. This is standard + on sufficiently-recent XFree86 systems, and possibly elsewhere. (It's + available if the file /usr/include/X11/extensions/Xrandr.h exists.) */ +#undef HAVE_RANDR + +/* Define this if the RANDR library is version 1.2 or newer. */ +#undef HAVE_RANDR_12 + +/* Define this if you have the XReadDisplay extension (I think this is an + SGI-only thing; it's in .) A few of the + screenhacks will take advantage of this if it's available. */ +#undef HAVE_READ_DISPLAY_EXTENSION + +/* Define to 1 if you have the `realpath' function. */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the `sbrk' function. */ +#undef HAVE_SBRK + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `setpriority' function. */ +#undef HAVE_SETPRIORITY + +/* Define to 1 if you have the `setrlimit' function. */ +#undef HAVE_SETRLIMIT + +/* Define this if your system uses 'shadow' passwords, that is, the passwords + live in /etc/shadow instead of /etc/passwd, and one reads them with + getspnam() instead of getpwnam(). (Note that SCO systems do some random + other thing; others might as well. See the ifdefs in driver/passwd-pwent.c + if you're having trouble related to reading passwords.) */ +#undef HAVE_SHADOW_PASSWD + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sigtimedwait' function. */ +#undef HAVE_SIGTIMEDWAIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `syslog' function. */ +#undef HAVE_SYSLOG + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the `uname' function. */ +#undef HAVE_UNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIL_H + +/* Define this if you have the XF86MiscSetGrabKeysState function (which allows + the Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash key sequences to be temporarily + disabled. Sadly, it doesn't affect Ctrl-Alt-BS or Ctrl-Alt-F1.) */ +#undef HAVE_XF86MISCSETGRABKEYSSTATE + +/* Define this if you have the functions XF86VidModeGetModeLine() and + XF86VidModeGetViewPort(), in support of virtual desktops where the X + server's root window is bigger than the actual screen. This is an XFree86 + thing, and probably doesn't exist elsewhere. (It's available if the file + /usr/include/X11/extensions/xf86vmode.h exists.) */ +#undef HAVE_XF86VMODE + +/* Define this if you have the functions XF86VidModeGetGamma() and + XF86VidModeSetGamma(), which allow clients to change the gamma response of + the monitor. This is an XFree86 4.0.x thing, and probably doesn't exist + elsewhere. (It's available if the file + /usr/include/X11/extensions/xf86vmode.h exists and has stuff about gamma in + it.) */ +#undef HAVE_XF86VMODE_GAMMA + +/* Define this if you have the functions XF86VidModeGetGammaRamp() and + XF86VidModeSetGammaRamp(), which provide finer-grained control than + XF86VidMode[GS]etGamma(). These appeared in XFree86 4.1.0. */ +#undef HAVE_XF86VMODE_GAMMA_RAMP + +/* Define this if you have the XHPDisableReset function (an HP only thing + which allows the Ctrl-Sh-Reset key sequence to be temporarily disabled.) */ +#undef HAVE_XHPDISABLERESET + +/* Define this if you have the Xinerama extension. This is standard on + sufficiently-recent XFree86 systems, and possibly elsewhere. (It's + available if the file /usr/include/X11/extensions/Xinerama.h exists.) */ +#undef HAVE_XINERAMA + +/* Define this if you have the Xinput extension. This is standard since X11R5, + and is thus almost everywhere. (It's available if the file + /usr/include/X11/extensions/XInput.h exists.) */ +#undef HAVE_XINPUT + +/* Define this if you have the XmComboBox Motif widget (Motif 2.0.) */ +#undef HAVE_XMCOMBOBOX + +/* Define this if you have the XML library. */ +#undef HAVE_XML + +/* Define this if you have the Xmu library. This is standard part of X, and if + your vendor doesn't ship it, you should report that as a bug. */ +#undef HAVE_XMU + +/* Define this if you have the XPM library installed. Some of the demos can + make use of this if it is available. */ +#undef HAVE_XPM + +/* Define this if you have the X Shared Memory Extension. */ +#undef HAVE_XSHM_EXTENSION + +/* Define to 1 if you have the `__argz_count' function. */ +#undef HAVE___ARGZ_COUNT + +/* Define to 1 if you have the `__argz_next' function. */ +#undef HAVE___ARGZ_NEXT + +/* Define to 1 if you have the `__argz_stringify' function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Define this to remove the option of locking the screen at all. */ +#undef NO_LOCKING + +/* This is the same as GETTEXT_PACKAGE, but for the glade generated code. */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Whether PAM should check the result of account modules when authenticating. + Only do this if you have account configured properly on your system. */ +#undef PAM_CHECK_ACCOUNT_TYPE + +/* If PAM is being used, this is the name of the PAM service that xscreensaver + will authenticate as. The default is "xscreensaver", which means that the + PAM library will look for an "xscreensaver" line in /etc/pam.conf, or (on + recent Linux systems) will look for a file called /etc/pam.d/xscreensaver. + Some systems might already have a PAM installation that is configured for + xlock, so setting this to "xlock" would also work in that case. */ +#undef PAM_SERVICE_NAME + +/* Define if you have PAM and pam_strerror() requires two arguments. */ +#undef PAM_STRERROR_TWO_ARGS + +/* Set the name of the password helper program, if any */ +#undef PASSWD_HELPER_PROGRAM + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define this to void* if you're using X11R4 or earlier. */ +#undef XPointer + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `int' if does not define. */ +#undef mode_t + +/* Define to `long int' if does not define. */ +#undef off_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..8b612ab8 --- /dev/null +++ b/config.sub @@ -0,0 +1,1788 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-04-24' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ + | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or1k-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 00000000..6c43d483 --- /dev/null +++ b/configure @@ -0,0 +1,16563 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="driver/subprocs.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_list= +ac_subst_vars='LTLIBOBJS +LIBOBJS +DEPEND_DEFINES +DEPEND_FLAGS +DEPEND +APPDEFAULTS +GTK_EXTRA_OBJS +HACK_CONF_DIR +PO_DATADIR +GTK_DATADIR +HACKDIR_FULL +HACKDIR +NOGNOME +GNOME22 +GNOME24 +GLFONT_OBJS +GLFPS_OBJS +JWZGLES_OBJS +GLE_KLUDGE +GLE_EXES +GL_KLUDGE +GL_MEN +GL_UTIL_EXES +SUID_EXES +RETIRED_GL_EXES +GL_EXES +JPEG_EXES +LOCK_OBJS +LOCK_SRCS +SAVER_GL_LIBS +SAVER_GL_OBJS +SAVER_GL_SRCS +XMU_LIBS +XMU_OBJS +XMU_SRCS +PASSWD_OBJS +PASSWD_SRCS +MEN_OSX +SCRIPTS_OSX +EXES_OSX +OBJCC +WITH_BROWSER +DEFAULT_TEXT_FILE +DEFAULT_IMAGE_DIRECTORY +DEFAULT_IMAGES_P +NEW_LOGIN_COMMAND_P +NEW_LOGIN_COMMAND +COMMENT_PAM_CHECK_ACCOUNT +HAVE_PAM_FAIL_DELAY +INSTALL_PAM +NEED_SETUID +INSTALL_DIRS +SETUID_HACKS +INSTALL_SETUID +PASSWD_LIBS +XINERAMA_LIBS +XDPMS_LIBS +GLE_LIBS +GL_LIBS +PTY_LIBS +XPM_LIBS +HACK_LIBS +JPEG_LIBS +XML_LIBS +GTK_LIBS +MOTIF_LIBS +SAVER_LIBS +ALL_DEMO_PROGRAMS +PREFERRED_DEMO_PROGRAM +INCLUDES +gnome_url_show_program +gnome_open_program +pkg_config +login_manager_tmp +MKINSTALLDIRS +POSUB +POFILES +INTLOBJS +INTLLIBS +INTLDEPS +INSTOBJEXT +GMOFILES +DATADIRNAME +CATOBJEXT +CATALOGS +XGETTEXT +GMSGFMT +MSGFMT +USE_NLS +ALLOCA +RANLIB +GETTEXT_PACKAGE +INTLTOOL_PERL +INTLTOOL_UPDATE +INTLTOOL_MERGE +INTLTOOL_EXTRACT +INTLTOOL_CAVES_RULE +INTLTOOL_XML_RULE +INTLTOOL_UI_RULE +INTLTOOL_SOUNDLIST_RULE +INTLTOOL_SHEET_RULE +INTLTOOL_SERVER_RULE +INTLTOOL_PONG_RULE +INTLTOOL_OAF_RULE +INTLTOOL_KEYS_RULE +INTLTOOL_DIRECTORY_RULE +INTLTOOL_DESKTOP_RULE +X_EXTRA_LIBS +X_LIBS +X_PRE_LIBS +X_CFLAGS +XMKMF +PERL +EGREP +GREP +SET_MAKE +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_x_app_defaults +enable_largefile +with_x +with_hackdir +enable_subdir +with_configdir +with_dpms_ext +with_xinerama_ext +with_xinput_ext +with_xf86vmode_ext +with_xf86gamma_ext +with_randr_ext +with_proc_interrupts +enable_locking +enable_root_passwd +with_pam +with_pam_service_name +enable_pam_check_account_type +with_kerberos +with_shadow +with_passwd_helper +with_login_manager +with_gtk +with_motif +with_gl +with_gle +with_gles +with_pixbuf +with_xpm +with_jpeg +with_xshm_ext +with_xdbe_ext +with_readdisplay +with_image_directory +with_text_file +with_browser +with_setuid_hacks +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +XMKMF' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + + +Configuration: + + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +X features: + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + +Screen locking options: + --enable-locking Compile in support for locking the display. + --disable-locking Do not allow locking at all. + + --enable-root-passwd Allow root passwd to unlock screen. + --disable-root-passwd Do not allow that. + --enable-pam-check-account-type + Whether PAM should check the result of account + modules when authenticating. Only do this if you + have account configured properly on your system. + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + + +Installation options: + --with-hackdir=DIR Where to install the hundreds of demo executables. + Default: `PREFIX/libexec/xscreensaver/' + --with-configdir=DIR Where to install the data files that describe each + of the display modes to the GUI. + Default: `PREFIX/share/xscreensaver/config/' + --with-x-app-defaults=DIR + Where to install xscreensaver configuration file. + + --with-dpms-ext Include support for the DPMS extension. + --with-xinerama-ext Include support for the XINERAMA extension. + --with-xinput-ext Include support for the XInput extension. + --with-xf86vmode-ext Include support for XFree86 virtual screens. + --with-xf86gamma-ext Include support for XFree86 gamma fading. + --with-randr-ext Include support for the X Resize+Rotate extension. + --with-proc-interrupts Include support for consulting the /proc/interrupts + file to notice keyboard activity. + --with-pam Include support for PAM (Pluggable Auth Modules.) + --with-pam-service-name NAME arg is the name of the PAM service that + xscreensaver will authenticate as. + --with-kerberos Include support for Kerberos authentication. + --with-shadow Include support for shadow password authentication. + --with-passwd-helper Include support for an external password + verification helper program. + --with-login-manager Put a "New Login" button on the unlock dialog that + runs a login manager like gdmflexiserver or kdmctl. + +User interface options: + + --with-gtk Use the Gtk toolkit for the user interface. + --with-motif Use the Motif toolkit for the user interface + (no longer supported.) + +Graphics options: + + --with-gl Build those demos which depend on OpenGL. + --with-gle Build those demos which depend on GLE + (the OpenGL "extrusion" library.) + --with-gles Target OpenGL ES 1.x API instead of OpenGL 1.3. + --with-pixbuf Include support for the GDK-Pixbuf library in some + demos, which will make it possible for them to read + GIF, JPEG, and PNG files as well. + --with-xpm Include support for XPM files in some demos. + (Not needed if Pixbuf is used.) + --with-jpeg Include support for the JPEG library. + --with-xshm-ext Include support for the Shared Memory extension. + --with-xdbe-ext Include support for the DOUBLE-BUFFER extension. + --with-readdisplay Include support for the XReadDisplay extension. + --with-image-directory Arg is the default directory from which some demos + will choose random images to display. + --with-text-file=FILE By default, some demos may display this file. + --with-browser=BROWSER Specify the web browser used to show the help URL. + --with-setuid-hacks Allow some demos to be installed `setuid root' + (which is needed in order to ping other hosts.) + + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + XMKMF Path to xmkmf, Makefile generator for X Window System + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -rf conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -rf conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -rf conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +as_fn_append ac_header_list " stdlib.h" +as_fn_append ac_header_list " unistd.h" +as_fn_append ac_header_list " sys/param.h" +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers config.h" + + +echo "current directory: `pwd`" +echo "command line was: $0 $@" + +############################################################################### +# +# Autoheader stuff +# +############################################################################### + + + + + + + +# This only ever existed in X11R4 and X11R5. +#AH_TEMPLATE([HAVE_XIDLE_EXTENSION], +# [Define this if you have the XIDLE extension installed. If you +# have the XIDLE extension, this is recommended. (You have this +# extension if the file /usr/include/X11/extensions/xidle.h +# exists.) Turning on this flag lets XScreenSaver work better with +# servers which support this extension; but it will still work +# with servers which do not suport it, so it's a good idea to +# compile in support for it if you can.]) + +# Using this extension will crash your X server and make fading not work. +#AH_TEMPLATE([HAVE_MIT_SAVER_EXTENSION], +# [Define this if you have the MIT-SCREEN-SAVER extension +# installed. See the caveats about this extension, above. +# (It's available if /usr/include/X11/extensions/scrnsaver.h +# exists.)]) + +# This only ever existed on SGI hardware. +#AH_TEMPLATE([HAVE_SGI_SAVER_EXTENSION], +# [Define this if you have the SGI SCREEN_SAVER extension. This is +# standard on Irix systems, and not available elsewhere.]) + +# This only ever existed on SGI hardware. +#AH_TEMPLATE([HAVE_SGI_VC_EXTENSION], +# [Define this if you have the SGI-VIDEO-CONTROL extension. This +# is standard on Irix systems, and not available elsewhere.]) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# After checking to see that --srcdir is correct (which AC_INIT does) +# check for some random other files that come later in the tar file, +# to make sure everything is here. +# +for d in driver utils hacks hacks/glx ; do + f=$srcdir/$d/Makefile.in + if test \! -r $f ; then + echo "" + echo "ERROR: The package is incomplete: $f does not exist." + echo " This probably means that your download was truncated." + echo "" + exit 1 + fi +done + +############################################################################### +# +# Function to figure out how to run the compiler. +# +############################################################################### + + + + +############################################################################### +# +# Check for availability of various gcc command-line options. +# +############################################################################### + + + + + + + +# Need to disable Objective C extensions in ANSI C on MacOS X to work +# around an Apple-specific gcc bug. +# + + +############################################################################### +# +# Function to figure out how to disable // comments in ANSI C code. +# +# (With recent gcc, this is done with "-std=c89". With older gcc, this +# is done by passing "-lang-c89" to cpp, by passing "-Wp,-lang-c89" to +# gcc. Old gcc doesn't support -std, and new gcc doesn't support -lang. +# so much for compatibility!) +# +# UPDATE: apparently there is NO WAY to tell gcc 3.2.2 to require that +# declarations preceed statements, without resorting to "-pedantic". +# This means that there is no way to get gcc3 to issue warnings that +# ensure that your code complies with the ANSI/ISO C89 standard, without +# also drowning in totally useless warnings. Thank you master may I +# have another. +# +# So, I give up, let's just use -pedantic. +# +############################################################################### + + + + + + +############################################################################### +# +# Function to figure out how to create directory trees. +# +############################################################################### + + + + +############################################################################### +# +# Function to check whether gettimeofday() exists, and how to call it. +# This may define HAVE_GETTIMEOFDAY and GETTIMEOFDAY_TWO_ARGS. +# +############################################################################### + + + + +############################################################################### +# +# Function to find perl5 (defines PERL and PERL_VERSION.) +# +############################################################################### + +# M4 sucks!! perl sucks too!! + +perl_version_cmd='print $]' + + + + + +############################################################################### +# +# Function to demand "bc". Losers. +# +############################################################################### + + + +############################################################################### +# +# Functions to check how to do ICMP PING requests. +# +############################################################################### + + + + + + +############################################################################### +# +# Functions to check for various X11 crap. +# +############################################################################### + +# Try and find the app-defaults directory. +# It sucks that autoconf doesn't do this already... +# + + +############################################################################### +# +# Handle the --with-x-app-defaults option HERE +# +############################################################################### + + +# Check whether --with-x-app-defaults was given. +if test "${with_x_app_defaults+set}" = set; then : + withval=$with_x_app_defaults; ac_cv_x_app_defaults="$withval" +else + eval ac_x_app_defaults="$withval" +fi + + + + + + + + + + + +# Random special-cases for X on certain pathological OSes. +# You know who you are. +# + + + + + +############################################################################### +# +# Some utility functions to make checking for X things easier. +# +############################################################################### + +# Like AC_CHECK_HEADER, but it uses the already-computed -I directories. +# + + +# Like AC_EGREP_HEADER, but it uses the already-computed -I directories. +# + + +# Like AC_TRY_COMPILE, but it uses the already-computed -I directories. +# + + + +# Like AC_CHECK_LIB, but it uses the already-computed -I and -L directories. +# Use this sparingly; it probably doesn't work very well on X programs. +# + + +# Like AC_TRY_RUN, but it uses the already-computed -I directories. +# (But not the -L directories!) +# + + + + +# Usage: HANDLE_X_PATH_ARG([variable_name], +# [--command-line-option], +# [descriptive string]) +# +# All of the --with options take three forms: +# +# --with-foo (or --with-foo=yes) +# --without-foo (or --with-foo=no) +# --with-foo=/DIR +# +# This function, HANDLE_X_PATH_ARG, deals with the /DIR case. When it sees +# a directory (string beginning with a slash) it checks to see whether +# /DIR/include and /DIR/lib exist, and adds them to $X_CFLAGS and $X_LIBS +# as appropriate. +# + + + + +############################################################################### +############################################################################### +# +# End of function definitions. Now start actually executing stuff. +# +############################################################################### +############################################################################### + +# WTF! autoconf emits this *way* too late. Do it earlier. +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + + +# random compiler setup +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -rf conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -rf conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -rf conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -rf conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -rf conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -rf conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -rf conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + if test -z "$GCC"; then + # not using GCC + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to request ANSI compilation" >&5 +$as_echo_n "checking how to request ANSI compilation... " >&6; } + case "$host" in + *-hpux* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: HPUX: adding -Ae" >&5 +$as_echo "HPUX: adding -Ae" >&6; } + CC="$CC -Ae" + ;; + *-aix* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: AIX: adding -qlanglvl=ansi -qhalt=e" >&5 +$as_echo "AIX: adding -qlanglvl=ansi -qhalt=e" >&6; } + CC="$CC -qlanglvl=ansi -qhalt=e" + ;; + *-dec-* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: DEC: adding -std1 -ieee" >&5 +$as_echo "DEC: adding -std1 -ieee" >&6; } + CC="$CC -std1" + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no idea" >&5 +$as_echo "no idea" >&6; } + ;; + esac + else + # using GCC + case "$host" in + *-solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Solaris: adding -D__EXTENSIONS__" >&5 +$as_echo "Solaris: adding -D__EXTENSIONS__" >&6; } + CC="$CC -D__EXTENSIONS__" + ;; + esac + fi + + OBJCC="$CC" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler works on ANSI C" >&5 +$as_echo_n "checking whether the compiler works on ANSI C... " >&6; } + if test "$cross_compiling" = yes; then : + as_fn_error $? "Couldn't build even a trivial ANSI C program: check CC." "$LINENO" 5 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + main(int ac, char **av) { return 0; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "Couldn't build even a trivial ANSI C program: check CC." "$LINENO" 5 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + + if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Turning on gcc compiler warnings." >&5 +$as_echo "Turning on gcc compiler warnings." >&6; } + CC="$CC -pedantic -Wall -Wstrict-prototypes -Wnested-externs -Wmissing-prototypes" + OBJCC="$OBJCC -Wall" + # As of gcc 3.4, we have "-Wdeclaration-after-statement" + # and so perhaps now we can do without -pedantic? + else + case "$host" in + *-irix5* |*-irix6.0-3* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Turning on SGI compiler warnings." >&5 +$as_echo "Turning on SGI compiler warnings." >&6; } + CC="$CC -fullwarn -use_readonly_const -rdata_shared -g3" + ;; +# *-dec-osf* ) +# if test -z "$GCC"; then +# AC_MSG_RESULT(Turning on DEC C compiler warnings.) +# CC="$CC -migrate -w0 -verbose -warnprotos" +# fi +# ;; + esac + fi + +if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wno-overlength-strings" >&5 +$as_echo_n "checking whether gcc accepts -Wno-overlength-strings... " >&6; } +if ${ac_cv_gcc_accepts_no_overlength+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -rf conftest.$ac_ext + touch conftest.$ac_ext + if ( ( gcc -c -Wno-overlength-strings conftest.$ac_ext -o/dev/null >/dev/null ) 2>&1 | \ + grep unrecognized >/dev/null ); then + ac_cv_gcc_accepts_no_overlength=no + else + ac_cv_gcc_accepts_no_overlength=yes + CC="$CC -Wno-overlength-strings" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_accepts_no_overlength" >&5 +$as_echo "$ac_cv_gcc_accepts_no_overlength" >&6; } + ac_gcc_accepts_no_overlength="$ac_cv_gcc_accepts_no_overlength" + fi + +if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wdeclaration-after-statement" >&5 +$as_echo_n "checking whether gcc accepts -Wdeclaration-after-statement... " >&6; } +if ${ac_cv_gcc_accepts_no_decl_after+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -rf conftest.$ac_ext + touch conftest.$ac_ext + if ( ( gcc -c -Wdeclaration-after-statement conftest.$ac_ext -o/dev/null >/dev/null ) 2>&1 | \ + grep unrecognized >/dev/null ); then + ac_cv_gcc_accepts_no_decl_after=no + else + ac_cv_gcc_accepts_no_decl_after=yes + CC="$CC -Wdeclaration-after-statement" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_accepts_no_decl_after" >&5 +$as_echo "$ac_cv_gcc_accepts_no_decl_after" >&6; } + ac_gcc_accepts_no_decl_after="$ac_cv_gcc_accepts_no_decl_after" + fi + +if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -no-cpp-precomp" >&5 +$as_echo_n "checking whether gcc accepts -no-cpp-precomp... " >&6; } +if ${ac_cv_gcc_accepts_no_cpp_precomp+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -rf conftest.$ac_ext + touch conftest.$ac_ext + if ( ( gcc -c -no-cpp-precomp conftest.$ac_ext -o/dev/null >/dev/null ) 2>&1 | \ + grep unrecognized >/dev/null ); then + ac_cv_gcc_accepts_no_cpp_precomp=no + else + ac_cv_gcc_accepts_no_cpp_precomp=yes + CC="$CC -no-cpp-precomp" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_accepts_no_cpp_precomp" >&5 +$as_echo "$ac_cv_gcc_accepts_no_cpp_precomp" >&6; } + ac_gcc_accepts_no_cpp_precomp="$ac_cv_gcc_accepts_no_cpp_precomp" + fi + +if test -n "$GCC"; then + + case "$host" in + *-darwin* ) + # Fucking Apple let // comments sneak into OpenGL headers, so + # we *must* allow // comments when compiling on Mac OS 10.6! FUCK! + ;; + *) + if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -std=c89" >&5 +$as_echo_n "checking whether gcc accepts -std=c89... " >&6; } +if ${ac_cv_gcc_accepts_std+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -rf conftest.$ac_ext + touch conftest.$ac_ext + if ( ( gcc -c -std=c89 conftest.$ac_ext -o/dev/null >/dev/null ) 2>&1 | \ + grep unrecognized >/dev/null ); then + ac_cv_gcc_accepts_std=no + else + ac_cv_gcc_accepts_std=yes + CC="$CC -std=c89" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_accepts_std" >&5 +$as_echo "$ac_cv_gcc_accepts_std" >&6; } + ac_gcc_accepts_std="$ac_cv_gcc_accepts_std" + fi + + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Disabling C++ comments in ANSI C code." >&5 +$as_echo "Disabling C++ comments in ANSI C code." >&6; } + # + # The reason that // comments are banned from xscreensaver is that gcc is + # basically the only compiler in the world that supports them in C code. + # All other vendors support them only in their C++ compilers, not in their + # ANSI C compilers. This means that it's a portability problem: every time + # these comments have snuck into the xscreensaver source code, I've gotten + # complaints about it the next day. So we turn off support for them in gcc + # as well to prevent them from accidentially slipping in. + # + if test "$ac_gcc_accepts_std" = yes ; then + # + # -std=c89 defines __STRICT_ANSI__, which we don't want. + # (That appears to be the only additional preprocessor symbol + # it defines, in addition to the syntax changes it makes.) + # + # -std=gnu89 is no good, because // comments were a GNU extension + # before they were in the ANSI C 99 spec... (gcc 2.96 permits // + # with -std=gnu89 but not with -std=c89.) + # + # $CC already contains "-std=c89" via AC_GCC_ACCEPTS_STD + CC="$CC -U__STRICT_ANSI__" +# else +# # The old way: +# CC="$CC -Wp,-lang-c89" + fi + fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -rf conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -rf conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -rf conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -rf conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -rf conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -rf conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + +ac_bc_result=`echo 6+9 | bc 2>/dev/null` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bc" >&5 +$as_echo_n "checking for bc... " >&6; } + if test "$ac_bc_result" = "15" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + echo '' + as_fn_error $? "Your system doesn't have \"bc\", which has been a standard + part of Unix since the 1970s. Come back when your vendor + has grown a clue." "$LINENO" 5 + fi + + +# stuff for Makefiles +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \"\${INSTALL} -d\" creates intermediate directories" >&5 +$as_echo_n "checking whether \"\${INSTALL} -d\" creates intermediate directories... " >&6; } +if ${ac_cv_install_d_creates_dirs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_install_d_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir 2>/dev/null + ${INSTALL} -d `pwd`/dir1/dir2 >/dev/null 2>&1 + if test -d dir1/dir2/. ; then + ac_cv_install_d_creates_dirs=yes + fi + cd .. 2>/dev/null + rm -rf conftestdir + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_install_d_creates_dirs" >&5 +$as_echo "$ac_cv_install_d_creates_dirs" >&6; } + + if test "$ac_cv_install_d_creates_dirs" = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \"mkdir -p\" creates intermediate directories" >&5 +$as_echo_n "checking whether \"mkdir -p\" creates intermediate directories... " >&6; } +if ${ac_cv_mkdir_p_creates_dirs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_mkdir_p_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir 2>/dev/null + mkdir -p dir1/dir2 >/dev/null 2>&1 + if test -d dir1/dir2/. ; then + ac_cv_mkdir_p_creates_dirs=yes + fi + cd .. 2>/dev/null + rm -rf conftestdir + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mkdir_p_creates_dirs" >&5 +$as_echo "$ac_cv_mkdir_p_creates_dirs" >&6; } + fi + + if test "$ac_cv_install_d_creates_dirs" = yes ; then + INSTALL_DIRS='${INSTALL} -d' + elif test "$ac_cv_mkdir_p_creates_dirs" = yes ; then + INSTALL_DIRS='mkdir -p' + else + # any other ideas? + INSTALL_DIRS='${INSTALL} -d' + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -rf conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# By default, autoconf sets INSTALL_SCRIPT to '${INSTALL_PROGRAM}'. +# That's wrong: it should be set to '${INSTALL}', so that one can +# implement the "install-strip" target properly (strip executables, +# but do not try to strip scripts.) +# +INSTALL_SCRIPT='${INSTALL}' + +# random libc stuff + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -rf conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -rf conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -rf conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -rf conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in unistd.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNISTD_H 1 +_ACEOF + +fi + +done + +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if ${ac_cv_type_signal+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if ${ac_cv_header_sys_wait_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_sys_wait_h=yes +else + ac_cv_header_sys_wait_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to call gettimeofday" >&5 +$as_echo_n "checking how to call gettimeofday... " >&6; } + if ${ac_cv_gettimeofday_args+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ +struct timeval tv; struct timezone tzp; + gettimeofday(&tv, &tzp); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_gettimeofday_args=2 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ +struct timeval tv; gettimeofday(&tv); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_gettimeofday_args=1 +else + ac_gettimeofday_args=0 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_gettimeofday_args=$ac_gettimeofday_args +fi + + ac_gettimeofday_args=$ac_cv_gettimeofday_args + if test "$ac_gettimeofday_args" = 1 ; then + $as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: one argument" >&5 +$as_echo "one argument" >&6; } + elif test "$ac_gettimeofday_args" = 2 ; then + $as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h + + $as_echo "#define GETTIMEOFDAY_TWO_ARGS 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: two arguments" >&5 +$as_echo "two arguments" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 +$as_echo "unknown" >&6; } + fi + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -rf conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + +for ac_func in select fcntl uname nice setpriority getcwd getwd putenv sbrk +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in sigaction syslog realpath setrlimit +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in setlocale +do : + ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" +if test "x$ac_cv_func_setlocale" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETLOCALE 1 +_ACEOF + +fi +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct icmp" >&5 +$as_echo_n "checking for struct icmp... " >&6; } +if ${ac_cv_have_icmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +int +main () +{ +struct icmp i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.icmp_type = ICMP_ECHO; + i.icmp_code = 0; + i.icmp_cksum = 0; + i.icmp_id = 0; + i.icmp_seq = 0; + si.sin_family = AF_INET; + #if defined(__DECC) || defined(_IP_VHL) + ip.ip_vhl = 0; + #else + ip.ip_hl = 0; + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_icmp=yes +else + ac_cv_have_icmp=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_icmp" >&5 +$as_echo "$ac_cv_have_icmp" >&6; } + if test "$ac_cv_have_icmp" = yes ; then + $as_echo "#define HAVE_ICMP 1" >>confdefs.h + + fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct icmphdr" >&5 +$as_echo_n "checking for struct icmphdr... " >&6; } +if ${ac_cv_have_icmphdr+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +int +main () +{ +struct icmphdr i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.type = ICMP_ECHO; + i.code = 0; + i.checksum = 0; + i.un.echo.id = 0; + i.un.echo.sequence = 0; + si.sin_family = AF_INET; + ip.ip_hl = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_icmphdr=yes +else + ac_cv_have_icmphdr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_icmphdr" >&5 +$as_echo "$ac_cv_have_icmphdr" >&6; } + if test "$ac_cv_have_icmphdr" = yes ; then + $as_echo "#define HAVE_ICMPHDR 1" >>confdefs.h + + fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getifaddrs" >&5 +$as_echo_n "checking for getifaddrs... " >&6; } +if ${ac_cv_have_getifaddrs+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include +int +main () +{ +struct ifaddrs *ifa; + getifaddrs (&ifa); + ifa->ifa_next = 0; + ifa->ifa_addr->sa_family = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_getifaddrs=yes +else + ac_cv_have_getifaddrs=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_getifaddrs" >&5 +$as_echo "$ac_cv_have_getifaddrs" >&6; } + if test "$ac_cv_have_getifaddrs" = yes ; then + $as_echo "#define HAVE_GETIFADDRS 1" >>confdefs.h + + fi +for ac_header in crypt.h sys/select.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_prog in perl5 perl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PERL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 +$as_echo "$PERL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PERL" && break +done + + if test -z "$PERL" ; then + PERL_VERSION=0 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking perl version" >&5 +$as_echo_n "checking perl version... " >&6; } +if ${ac_cv_perl_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_perl_version=`$PERL -e "$perl_version_cmd"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_perl_version" >&5 +$as_echo "$ac_cv_perl_version" >&6; } + PERL_VERSION=$ac_cv_perl_version + fi + + +if test -z "$PERL" ; then + # don't let it be blank... + PERL=/usr/bin/perl +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 +$as_echo_n "checking for X... " >&6; } + + +# Check whether --with-x was given. +if test "${with_x+set}" = set; then : + withval=$with_x; +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + case $x_includes,$x_libraries in #( + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( + *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +rm -f -r conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + cat >Imakefile <<'_ACEOF' +incroot: + @echo incroot='${INCROOT}' +usrlibdir: + @echo usrlibdir='${USRLIBDIR}' +libdir: + @echo libdir='${LIBDIR}' +_ACEOF + if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. + for ac_var in incroot usrlibdir libdir; do + eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" + done + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl dylib la dll; do + if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && + test -f "$ac_im_libdir/libX11.$ac_extension"; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ac_x_includes= ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /usr/lib64 | /lib | /lib64) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac + fi + cd .. + rm -f -r conftest.dir +fi + +# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R7/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include + +/usr/include/X11 +/usr/include/X11R7 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 + +/usr/local/X11/include +/usr/local/X11R7/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include + +/usr/local/include/X11 +/usr/local/include/X11R7 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 + +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include + +/usr/openwin/include +/usr/openwin/share/include' + +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Xlib.h. + # First, try using that file with no special directory specified. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # We can compile using X headers with no special include directory. +ac_x_includes= +else + for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Xlib.h"; then + ac_x_includes=$ac_dir + break + fi +done +fi +rm -rf conftest.err conftest.i conftest.$ac_ext +fi # $ac_x_includes = no + +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lX11 $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +XrmInitialize () + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries= +else + LIBS=$ac_save_LIBS +for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl dylib la dll; do + if test -r "$ac_dir/libX11.$ac_extension"; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi # $ac_x_libraries = no + +case $ac_x_includes,$ac_x_libraries in #( + no,* | *,no | *\'*) + # Didn't find X, or a directory has "'" in its name. + ac_cv_have_x="have_x=no";; #( + *) + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$ac_x_includes'\ + ac_x_libraries='$ac_x_libraries'" +esac +fi +;; #( + *) have_x=yes;; + esac + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 +$as_echo "$have_x" >&6; } + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$x_includes'\ + ac_x_libraries='$x_libraries'" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 +$as_echo "libraries $x_libraries, headers $x_includes" >&6; } +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + +$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 +$as_echo_n "checking whether -R must be followed by a space... " >&6; } + ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" + ac_xsave_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + X_LIBS="$X_LIBS -R$x_libraries" +else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + X_LIBS="$X_LIBS -R $x_libraries" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 +$as_echo "neither works" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_c_werror_flag=$ac_xsave_c_werror_flag + LIBS=$ac_xsave_LIBS + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn Johnson says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And Karl Berry says + # the Alpha needs dnet_stub (dnet does not exist). + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XOpenDisplay (); +int +main () +{ +return XOpenDisplay (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 +$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } +if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dnet_ntoa (); +int +main () +{ +return dnet_ntoa (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dnet_dnet_ntoa=yes +else + ac_cv_lib_dnet_dnet_ntoa=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } +if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 +$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } +if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet_stub $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dnet_ntoa (); +int +main () +{ +return dnet_ntoa (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dnet_stub_dnet_ntoa=yes +else + ac_cv_lib_dnet_stub_dnet_ntoa=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +fi + + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_xsave_LIBS" + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to T.E. Dickey. + # The functions gethostbyname, getservbyname, and inet_addr are + # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. + ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes; then : + +fi + + if test $ac_cv_func_gethostbyname = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +fi + + if test $ac_cv_lib_nsl_gethostbyname = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 +$as_echo_n "checking for gethostbyname in -lbsd... " >&6; } +if ${ac_cv_lib_bsd_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bsd_gethostbyname=yes +else + ac_cv_lib_bsd_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 +$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } +if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" +fi + + fi + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says Simon Leinen: it contains gethostby* + # variants that don't use the name server (or something). -lsocket + # must be given before -lnsl if both are needed. We assume that + # if connect needs -lnsl, so does gethostbyname. + ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" +if test "x$ac_cv_func_connect" = xyes; then : + +fi + + if test $ac_cv_func_connect = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +$as_echo_n "checking for connect in -lsocket... " >&6; } +if ${ac_cv_lib_socket_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char connect (); +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_connect=yes +else + ac_cv_lib_socket_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +$as_echo "$ac_cv_lib_socket_connect" >&6; } +if test "x$ac_cv_lib_socket_connect" = xyes; then : + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +fi + + fi + + # Guillermo Gomez says -lposix is necessary on A/UX. + ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" +if test "x$ac_cv_func_remove" = xyes; then : + +fi + + if test $ac_cv_func_remove = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 +$as_echo_n "checking for remove in -lposix... " >&6; } +if ${ac_cv_lib_posix_remove+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lposix $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char remove (); +int +main () +{ +return remove (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_posix_remove=yes +else + ac_cv_lib_posix_remove=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 +$as_echo "$ac_cv_lib_posix_remove" >&6; } +if test "x$ac_cv_lib_posix_remove" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" +if test "x$ac_cv_func_shmat" = xyes; then : + +fi + + if test $ac_cv_func_shmat = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 +$as_echo_n "checking for shmat in -lipc... " >&6; } +if ${ac_cv_lib_ipc_shmat+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lipc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shmat (); +int +main () +{ +return shmat (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ipc_shmat=yes +else + ac_cv_lib_ipc_shmat=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 +$as_echo "$ac_cv_lib_ipc_shmat" >&6; } +if test "x$ac_cv_lib_ipc_shmat" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS=$LDFLAGS + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # John Interrante, Karl Berry + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 +$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } +if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char IceConnectionNumber (); +int +main () +{ +return IceConnectionNumber (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ICE_IceConnectionNumber=yes +else + ac_cv_lib_ICE_IceConnectionNumber=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +fi + + LDFLAGS=$ac_save_LDFLAGS + +fi + + +if test "$have_x" != yes; then + as_fn_error $? "Couldn't find X11 headers/libs. Try \`$0 --help'." "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X app-defaults directory" >&5 +$as_echo_n "checking for X app-defaults directory... " >&6; } +if ${ac_cv_x_app_defaults+:} false; then : + $as_echo_n "(cached) " >&6 +else + + rm -fr conftestdir + if mkdir conftestdir; then + cd conftestdir 2>/dev/null + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_x_app_defaults="${XAPPLOADDIR}"' +EOF + if (xmkmf) >/dev/null 2>&1 && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which'd confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + fi + cd .. 2>/dev/null + rm -fr conftestdir + fi + if test x"$ac_x_app_defaults" = x; then + + # Look for the directory under a standard set of common directories. + # Check X11 before X11Rn because it's often a symlink to the current release. + for ac_dir in \ + /usr/X11/lib/app-defaults \ + /usr/X11R6/lib/app-defaults \ + /usr/X11R6/lib/X11/app-defaults \ + /usr/X11R5/lib/app-defaults \ + /usr/X11R5/lib/X11/app-defaults \ + /usr/X11R4/lib/app-defaults \ + /usr/X11R4/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/lib/X11R6/app-defaults \ + /usr/lib/X11R5/app-defaults \ + /usr/lib/X11R4/app-defaults \ + \ + /usr/local/X11/lib/app-defaults \ + /usr/local/X11R6/lib/app-defaults \ + /usr/local/X11R5/lib/app-defaults \ + /usr/local/X11R4/lib/app-defaults \ + \ + /usr/local/lib/X11/app-defaults \ + /usr/local/lib/X11R6/app-defaults \ + /usr/local/lib/X11R6/X11/app-defaults \ + /usr/local/lib/X11R5/app-defaults \ + /usr/local/lib/X11R5/X11/app-defaults \ + /usr/local/lib/X11R4/app-defaults \ + /usr/local/lib/X11R4/X11/app-defaults \ + \ + /usr/X386/lib/X11/app-defaults \ + /usr/x386/lib/X11/app-defaults \ + /usr/XFree86/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/local/lib/X11/app-defaults \ + /usr/unsupported/lib/X11/app-defaults \ + /usr/athena/lib/X11/app-defaults \ + /usr/local/x11r5/lib/X11/app-defaults \ + /usr/lpp/Xamples/lib/X11/app-defaults \ + /lib/usr/lib/X11/app-defaults \ + \ + /usr/openwin/lib/app-defaults \ + /usr/openwin/lib/X11/app-defaults \ + /usr/openwin/share/lib/app-defaults \ + /usr/openwin/share/lib/X11/app-defaults \ + \ + /X11R6/lib/app-defaults \ + /X11R5/lib/app-defaults \ + /X11R4/lib/app-defaults \ + ; \ + do + if test -d "$ac_dir"; then + ac_x_app_defaults=$ac_dir + break + fi + done + + fi + if test x"$ac_x_app_defaults" = x; then + ac_cv_x_app_defaults="/usr/lib/X11/app-defaults" + else + # Record where we found app-defaults for the cache. + ac_cv_x_app_defaults="$ac_x_app_defaults" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_x_app_defaults" >&5 +$as_echo "$ac_cv_x_app_defaults" >&6; } + eval ac_x_app_defaults="$ac_cv_x_app_defaults" +case "$host" in + *-hpux*) + + # The following arcana was gleaned from conversations with + # Eric Schwartz : + # + # On HPUX 10.x, the parts of X that HP considers "standard" live in + # /usr/{include,lib}/X11R6/. The parts that HP doesn't consider + # "standard", notably, Xaw and Xmu, live in /usr/contrib/X11R6/. + # Yet /usr/contrib/X11R6/ comes preinstalled on all HPUX systems. + # Also, there are symlinks from /usr/include/ and /usr/lib/ into + # /usr/{include,lib}/X11R6/, so that (if you don't use Xmu at all) + # you don't need any -I or -L arguments. + # + # On HPUX 9.x, /usr/{include,lib}/X11R5/ and /usr/contrib/X11R5/ + # are the same division as 10.x. However, there are no symlinks to + # the X stuff from /usr/include/ and /usr/lib/, so -I and -L + # arguments are always necessary. + # + # However, X11R6 was available on HPUX 9.x as a patch: if that + # patch was installed, then all of X11R6 went in to + # /usr/contrib/X11R6/ (there was no /usr/{include,lib}/X11R6/.) + # + # HPUX 8.x was the same as 9.x, but was X11R4 instead (I don't know + # whether R5 was available as a patch; R6 undoubtedly was not.) + # + # So. We try and use the highest numbered pair of + # /usr/{include,lib}/X11R?/ and /usr/contrib/X11R?/{include,lib}/ + # that are available. We do not mix and match different versions + # of X. + # + # Question I still don't know the answer to: (do you?) + # + # * On HPUX 9.x, where /usr/include/X11R5/ was standard, and + # /usr/contrib/X11R6/ could be installed as a patch, what was in + # that contrib directory? Did it contain so-called "standard" + # X11R6, or did it include Xaw and Xmu as well? If the former, + # where did one find Xaw and Xmu on 9.x R6 systems? Would this + # be a situation where one had to reach into the R5 headers and + # libs to find Xmu? That is, must both R6 and R5 directories + # be on the -I and -L lists in that case? + # + for version in X11R6 X11R5 X11R4 ; do + # if either pair of directories exists... + if test -d /usr/include/$version || test -d /usr/contrib/$version/include + then + # if contrib exists, use it... + if test -d /usr/contrib/$version/include ; then + X_CFLAGS="$X_CFLAGS -I/usr/contrib/$version/include" + X_LIBS="$X_LIBS -L/usr/contrib/$version/lib" + fi + # if the "standard" one exists, use it. + if test -d /usr/include/$version ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/$version" + X_LIBS="$X_LIBS -L/usr/lib/$version" + fi + # since at least one of the pair exists, go no farther. + break + fi + done + + # Now find Motif. Thanks for not making xmkmf find this by + # default, you losers. + # + if test -d /usr/include/Motif2.1 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif2.1" + X_LIBS="$X_LIBS -L/usr/lib/Motif2.1" + elif test -d /usr/include/Motif1.2 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.2" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.2" + elif test -d /usr/include/Motif1.1 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.1" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.1" + fi + + # Now let's check for the pseudo-standard locations for OpenGL and XPM. + # + if test -d /opt/graphics/OpenGL/include ; then + # HP-UX 10.20 puts it here + X_CFLAGS="-I/opt/graphics/OpenGL/include $X_CFLAGS" + X_LIBS="-L/opt/graphics/OpenGL/lib $X_LIBS" + elif test -d /opt/Mesa/lib ; then + X_CFLAGS="-I/opt/Mesa/include $X_CFLAGS" + X_LIBS="-L/opt/Mesa/lib $X_LIBS" + fi + + + if test -d /opt/xpm/lib/X11 ; then + X_CFLAGS="-I/opt/xpm/include $X_CFLAGS" + X_LIBS="-L/opt/xpm/lib/X11 $X_LIBS" + fi + + # On HPUX, default to installing in /opt/xscreensaver/ instead of + # in /usr/local/, unless there is already an xscreensaver in + # /usr/local/bin/. This can be overridden with the --prefix arg + # to configure. I'm not sure this is the right thing to do, but + # Richard Lloyd says so... + # + if test \! -x /usr/local/bin/xscreensaver ; then + ac_default_prefix=/opt/xscreensaver + fi + + ;; + *-solaris*) + + # Thanks for not making xmkmf find this by default, pinheads. + # And thanks for moving things around again, too. Is this + # really the standard location now? What happened to the + # joke that this kind of thing went in /opt? + # cthomp says "answer: CDE (Common Disorganized Environment)" + # + if test -f /usr/dt/include/Xm/Xm.h ; then + X_CFLAGS="$X_CFLAGS -I/usr/dt/include" + MOTIF_LIBS="$MOTIF_LIBS -L/usr/dt/lib -R/usr/dt/lib" + + # Some versions of Slowlaris Motif require -lgen. But not all. Why? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for regcmp in -lgen" >&5 +$as_echo_n "checking for regcmp in -lgen... " >&6; } +if ${ac_cv_lib_gen_regcmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgen $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char regcmp (); +int +main () +{ +return regcmp (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gen_regcmp=yes +else + ac_cv_lib_gen_regcmp=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_regcmp" >&5 +$as_echo "$ac_cv_lib_gen_regcmp" >&6; } +if test "x$ac_cv_lib_gen_regcmp" = xyes; then : + MOTIF_LIBS="$MOTIF_LIBS -lgen" +fi + + fi + + ;; + *-darwin*) + + # On MacOS X (10.x with "fink"), many things are under /sw/. + # + if test -d /sw/include ; then + X_CFLAGS="-I/sw/include $X_CFLAGS" + X_LIBS="-L/sw/lib $X_LIBS" + fi + ;; + esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XPointer" >&5 +$as_echo_n "checking for XPointer... " >&6; } +if ${ac_cv_xpointer+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +XPointer foo = (XPointer) 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_xpointer=yes +else + ac_cv_xpointer=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_xpointer" >&5 +$as_echo "$ac_cv_xpointer" >&6; } + if test "$ac_cv_xpointer" != yes; then + $as_echo "#define XPointer char*" >>confdefs.h + + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether this is MacOS X" >&5 +$as_echo_n "checking whether this is MacOS X... " >&6; } + ac_macosx=no + case "$host" in + *-apple-darwin* ) + ac_macosx=yes + ;; + esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_macosx" >&5 +$as_echo "$ac_macosx" >&6; } + + +############################################################################### +# +# Gettext support +# +############################################################################### + + + +if test -n ""; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= " >&5 +$as_echo_n "checking for intltool >= ... " >&6; } + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo | awk -F. '{ printf "%d", $1 * 100 + $2; }'` + INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { printf $2; }' < intltool-update.in` + + INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split($2, VERSION, "."); printf "%d\n", VERSION[1] * 100 + VERSION[2];}' < intltool-update.in` + + + if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5 +$as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool or later." >&5 +$as_echo "$INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool or later." >&6; } + exit 1 + fi +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -k -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -o -p' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -o -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + + + + + + + + + + + + + +# Use the tools built into the package, not the ones that are installed. + +INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract' +INTLTOOL_MERGE='$(top_builddir)/intltool-merge' +INTLTOOL_UPDATE='$(top_builddir)/intltool-update' + + + + + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INTLTOOL_PERL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INTLTOOL_PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL +if test -n "$INTLTOOL_PERL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5 +$as_echo "$INTLTOOL_PERL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -z "$INTLTOOL_PERL"; then + as_fn_error $? "perl not found; required for intltool" "$LINENO" 5 +fi +if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then + as_fn_error $? "perl 5.x required for intltool" "$LINENO" 5 +fi + +# Remove file type tags (using []) from po/POTFILES. + + + + + + + +# Manually sed perl in so people don't have to put the intltool scripts in AC_OUTPUT. + +ac_config_commands="$ac_config_commands default-1" + + + +GETTEXT_PACKAGE=xscreensaver + +cat >>confdefs.h <<_ACEOF +#define GETTEXT_PACKAGE "$GETTEXT_PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$GETTEXT_PACKAGE" +_ACEOF + + + +ALL_LINGUAS="ca da de es et fi fr hu it ja ko nb nl pl pt pt_BR ru sk sv vi wa zh_CN zh_TW" +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -rf conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +int +main (int argc, char **argv) +{ + return find_stack_direction (0, argc + !argv + 20) < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + + + + for ac_header in $ac_header_list +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + +for ac_func in getpagesize +do : + ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" +if test "x$ac_cv_func_getpagesize" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETPAGESIZE 1 +_ACEOF + +fi +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 +$as_echo_n "checking for working mmap... " >&6; } +if ${ac_cv_func_mmap_fixed_mapped+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_mmap_fixed_mapped=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +/* malloc might have been renamed as rpl_malloc. */ +#undef malloc + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the file system buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propagated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ + +#include +#include + +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H +char *malloc (); +#endif + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +int +main () +{ + char *data, *data2, *data3; + const char *cdata2; + int i, pagesize; + int fd, fd2; + + pagesize = getpagesize (); + + /* First, make a file with some known garbage in it. */ + data = (char *) malloc (pagesize); + if (!data) + return 1; + for (i = 0; i < pagesize; ++i) + *(data + i) = rand (); + umask (0); + fd = creat ("conftest.mmap", 0600); + if (fd < 0) + return 2; + if (write (fd, data, pagesize) != pagesize) + return 3; + close (fd); + + /* Next, check that the tail of a page is zero-filled. File must have + non-zero length, otherwise we risk SIGBUS for entire page. */ + fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); + if (fd2 < 0) + return 4; + cdata2 = ""; + if (write (fd2, cdata2, 1) != 1) + return 5; + data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); + if (data2 == MAP_FAILED) + return 6; + for (i = 0; i < pagesize; ++i) + if (*(data2 + i)) + return 7; + close (fd2); + if (munmap (data2, pagesize)) + return 8; + + /* Next, try to mmap the file at a fixed address which already has + something else allocated at it. If we can, also make sure that + we see the same garbage. */ + fd = open ("conftest.mmap", O_RDWR); + if (fd < 0) + return 9; + if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + return 10; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + return 11; + + /* Finally, make sure that changes to the mapped area do not + percolate back to the file as seen by read(). (This is a bug on + some variants of i386 svr4.0.) */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = (char *) malloc (pagesize); + if (!data3) + return 12; + if (read (fd, data3, pagesize) != pagesize) + return 13; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + return 14; + close (fd); + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_mmap_fixed_mapped=yes +else + ac_cv_func_mmap_fixed_mapped=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 +$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } +if test $ac_cv_func_mmap_fixed_mapped = yes; then + +$as_echo "#define HAVE_MMAP 1" >>confdefs.h + +fi +rm -rf conftest.mmap conftest.txt + + + for ac_header in argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h sys/param.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ +strdup __argz_count __argz_stringify __argz_next +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + if test $ac_cv_header_locale_h = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5 +$as_echo_n "checking for LC_MESSAGES... " >&6; } +if ${am_cv_val_LC_MESSAGES+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +return LC_MESSAGES + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_val_LC_MESSAGES=yes +else + am_cv_val_LC_MESSAGES=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_val_LC_MESSAGES" >&5 +$as_echo "$am_cv_val_LC_MESSAGES" >&6; } + if test $am_cv_val_LC_MESSAGES = yes; then + +$as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h + + fi + fi + USE_NLS=yes + + + nls_cv_force_use_gnu_gettext="no" + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" +if test "x$ac_cv_header_libintl_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in libc" >&5 +$as_echo_n "checking for dgettext in libc... " >&6; } +if ${gt_cv_func_dgettext_libc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +return (int) dgettext ("","") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_dgettext_libc=yes +else + gt_cv_func_dgettext_libc=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_dgettext_libc" >&5 +$as_echo "$gt_cv_func_dgettext_libc" >&6; } + + if test "$gt_cv_func_dgettext_libc" != "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bindtextdomain in -lintl" >&5 +$as_echo_n "checking for bindtextdomain in -lintl... " >&6; } +if ${ac_cv_lib_intl_bindtextdomain+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char bindtextdomain (); +int +main () +{ +return bindtextdomain (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_bindtextdomain=yes +else + ac_cv_lib_intl_bindtextdomain=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_bindtextdomain" >&5 +$as_echo "$ac_cv_lib_intl_bindtextdomain" >&6; } +if test "x$ac_cv_lib_intl_bindtextdomain" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in libintl" >&5 +$as_echo_n "checking for dgettext in libintl... " >&6; } +if ${gt_cv_func_dgettext_libintl+:} false; then : + $as_echo_n "(cached) " >&6 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in -lintl" >&5 +$as_echo_n "checking for dgettext in -lintl... " >&6; } +if ${ac_cv_lib_intl_dgettext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dgettext (); +int +main () +{ +return dgettext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_dgettext=yes +else + ac_cv_lib_intl_dgettext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_dgettext" >&5 +$as_echo "$ac_cv_lib_intl_dgettext" >&6; } +if test "x$ac_cv_lib_intl_dgettext" = xyes; then : + gt_cv_func_dgettext_libintl=yes +else + gt_cv_func_dgettext_libintl=no +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_dgettext_libintl" >&5 +$as_echo "$gt_cv_func_dgettext_libintl" >&6; } +fi + + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + LIBS="$LIBS -lintl"; + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + +$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 +$as_echo "$MSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + if test "$MSGFMT" != "no"; then + for ac_func in dcgettext +do : + ac_fn_c_check_func "$LINENO" "dcgettext" "ac_cv_func_dcgettext" +if test "x$ac_cv_func_dcgettext" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DCGETTEXT 1 +_ACEOF + +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GMSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT +if test -n "$GMSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 +$as_echo "$GMSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XGETTEXT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 +$as_echo "$XGETTEXT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + CATOBJEXT=.gmo + DATADIRNAME=share +else + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + INSTOBJEXT=.mo + fi + fi + + # Added by Martin Baulig 12/15/98 for libc5 systems + if test "$gt_cv_func_dgettext_libc" != "yes" \ + && test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS=-lintl + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + fi + +fi + + + + if test "$CATOBJEXT" = "NONE"; then + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" != "yes"; then + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + else + CATOBJEXT= + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5 +$as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; } + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + ac_config_commands="$ac_config_commands default-2" + + + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + + + + + + + + + + + + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 +$as_echo_n "checking for catalogs to be installed... " >&6; } + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 +$as_echo "$LINGUAS" >&6; } + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + test -d po || mkdir po + if test "$CATOBJEXT" = ".cat"; then + ac_fn_c_check_header_mongrel "$LINENO" "linux/version.h" "ac_cv_header_linux_version_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_version_h" = xyes; then : + msgformat=linux +else + msgformat=xopen +fi + + + + sed -e '/^#/d' $srcdir/po/$msgformat-msg.sed > po/po2msg.sed + fi + + MKINSTALLDIRS= +# +# jwz: fuck this! it puts hardcoded pathnames into the generated Makefiles! +# +# if test -n "$ac_aux_dir"; then +# MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" +# fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + + # jwz: you know what, screw it. Let's just use the version that I + # already computed in configure.in, instead of this version that came + # with the i18n crud, ok? + MKINSTALLDIRS="$INSTALL_DIRS" + + + + + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + +MKINSTALLDIRS="$INSTALL_DIRS" + + +############################################################################### +# +# Check for -lXmu (some fucked up vendors don't ship it...) +# +############################################################################### + +have_xmu=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/Xmu/Error.h" "ac_cv_header_X11_Xmu_Error_h" "#include + #include + #include +" +if test "x$ac_cv_header_X11_Xmu_Error_h" = xyes; then : + have_xmu=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" +if test "$have_xmu" = no ; then + XMU_SRCS='$(UTILS_SRC)/xmu.c' + XMU_OBJS='$(UTILS_BIN)/xmu.o' + XMU_LIBS='' +else + XMU_SRCS='' + XMU_OBJS='' + XMU_LIBS='-lXmu' + $as_echo "#define HAVE_XMU 1" >>confdefs.h + +fi + + +############################################################################### +# +# Check for the SunOS 4.1.x _get_wmShellWidgetClass bug. +# See comp.windows.x FAQ question 124. The right fix is to +# get OpenWindows 3.0 patches 100512-02 and 100573-03. +# +############################################################################### + +if test "$have_xmu" = yes ; then + case "$host" in + *-sunos4*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the SunOS 4.1.x _get_wmShellWidgetClass bug" >&5 +$as_echo_n "checking for the SunOS 4.1.x _get_wmShellWidgetClass bug... " >&6; } +if ${ac_cv_sunos_xmu_bug+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_LDFLAGS="$LDFLAGS" + if test \! -z "$x_libraries" ; then + LDFLAGS="$LDFLAGS -L$x_libraries" + fi + # Note: this trick never works! (Generally.) + # We're only getting away with using AC_TRY_LINK + # with X libraries because we know it's SunOS. + LDFLAGS="$LDFLAGS -lXmu -lXt -lX11 -lXext -lm" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sunos_xmu_bug=no +else + ac_cv_sunos_xmu_bug=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$ac_save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sunos_xmu_bug" >&5 +$as_echo "$ac_cv_sunos_xmu_bug" >&6; } + if test "$ac_cv_sunos_xmu_bug" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler understands -static" >&5 +$as_echo_n "checking whether the compiler understands -static... " >&6; } +if ${ac_cv_ld_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -static" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_ld_static=yes +else + ac_cv_ld_static=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$ac_save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ld_static" >&5 +$as_echo "$ac_cv_ld_static" >&6; } + if test "$ac_cv_ld_static" = yes ; then + LDFLAGS="$LDFLAGS -static" + else + LDFLAGS="$LDFLAGS -Bstatic" + fi + fi + ;; + esac +fi + + +############################################################################### +# +# Handle the --with-hackdir option +# +############################################################################### + +have_hackdir=yes +with_hackdir_req=unspecified + +# Check whether --with-hackdir was given. +if test "${with_hackdir+set}" = set; then : + withval=$with_hackdir; with_hackdir="$withval"; with_hackdir_req="$withval" +else + with_hackdir=yes +fi + + +if test x"$with_hackdir" = xyes; then + HACKDIR='${libexecdir}/xscreensaver' +elif test x"$with_hackdir" = xno; then + HACKDIR='${bindir}' +else + HACKDIR=$with_hackdir +fi + +# canonicalize slashes. +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` + +# Expand HACKDIR as HACKDIR_FULL +HACKDIR_FULL=`eval eval eval eval eval eval eval eval eval echo $HACKDIR` + +# This option used to be called --enable-subdir; make sure that is no longer +# used, since configure brain-damagedly ignores unknown --enable options. + +obsolete_enable= +# Check whether --enable-subdir was given. +if test "${enable_subdir+set}" = set; then : + enableval=$enable_subdir; obsolete_enable=yes +fi + +if test -n "$obsolete_enable"; then + echo "error: the --enable-subdir option has been replaced with" + echo " the new --with-hackdir option; see \`configure --help'" + echo " for more information." + exit 1 +fi + + +############################################################################### +# +# Handle the --with-configdir option +# Help for --with-x-app-defaults option added. +# +############################################################################### + +have_configdir=yes +with_configdir_req=unspecified + +# Check whether --with-configdir was given. +if test "${with_configdir+set}" = set; then : + withval=$with_configdir; with_configdir="$withval"; with_configdir_req="$withval" +else + with_configdir=yes +fi + + +if test x"$with_configdir" = xyes; then + HACK_CONF_DIR='${datadir}/xscreensaver/config' +elif test x"$with_configdir" = xno; then + echo "error: must be yes, or a pathname: --with-configdir=$with_configdir" + exit 1 +else + # there must be a better way than this... + if test -z "`echo $with_configdir | sed 's@^/.*@@'`" ; then + # absolute path + HACK_CONF_DIR=$with_configdir + else + # relative path + HACK_CONF_DIR="\${exec_prefix}$with_configdir" + fi +fi + + + + +############################################################################### +# +# Check for the SGI SCREEN_SAVER server extension. +# +############################################################################### + +#have_sgi=no +#with_sgi_req=unspecified +#AC_ARG_WITH(sgi-ext, +#[Except where noted, all of the --with options below can also take a +#directory argument: for example, `--with-motif=/opt/Motif'. That would +#cause /opt/Motif/include/ to be added to the -I list, and /opt/Motif/lib/ +#to be added to the -L list, assuming those directories exist. +# +#By default, support for each of these options will be built in, if the +#relevant library routines exist. At run time, they will then be used +#only if the X server being used supports them. Each --with option has +#a corresponding --without option, to override building support for them +#at all. +# +#Screen blanking and idle-detection options: +# +# --with-sgi-ext Include support for the SGI SCREEN_SAVER extension.], +# [with_sgi="$withval"; with_sgi_req="$withval"],[with_sgi=yes]) +# +#HANDLE_X_PATH_ARG(with_sgi, --with-sgi-ext, SGI SCREEN_SAVER) +# +#if test "$with_sgi" = yes; then +# AC_CHECK_X_HEADER(X11/extensions/XScreenSaver.h, +# [have_sgi=yes +# AC_DEFINE(HAVE_SGI_SAVER_EXTENSION)],, +# [#include ]) +# +#elif test "$with_sgi" != no; then +# echo "error: must be yes or no: --with-sgi-ext=$with_sgi" +# exit 1 +#fi + + +############################################################################### +# +# Check for the XIDLE server extension. +# +############################################################################### + +#have_xidle=no +#with_xidle_req=unspecified +#AC_ARG_WITH(xidle-ext, +#[ --with-xidle-ext Include support for the XIDLE extension.], +# [with_xidle="$withval"; with_xidle_req="$withval"],[with_xidle=yes]) +# +#HANDLE_X_PATH_ARG(with_xidle, --with-xidle-ext, XIDLE) +# +#if test "$with_xidle" = yes; then +# AC_CHECK_X_HEADER(X11/extensions/xidle.h, +# [have_xidle=yes +# AC_DEFINE(HAVE_XIDLE_EXTENSION)],, +# [#include ]) +#elif test "$with_xidle" != no; then +# echo "error: must be yes or no: --with-xidle-ext=$with_xidle" +# exit 1 +#fi + + +############################################################################### +# +# Check for the SGI-VIDEO-CONTROL server extension. +# +############################################################################### + +#have_sgivc=no +#with_sgivc_req=unspecified +#AC_ARG_WITH(sgivc-ext, +#[ --with-sgivc-ext Include support for the SGI-VIDEO-CONTROL extension.], +# [with_sgivc="$withval"; with_sgivc_req="$withval"],[with_sgivc=yes]) +# +#HANDLE_X_PATH_ARG(with_sgivc, --with-sgivc-ext, SGI-VIDEO-CONTROL) +# +#if test "$with_sgivc" = yes; then +# +# # first check for XSGIvc.h +# AC_CHECK_X_HEADER(X11/extensions/XSGIvc.h, [have_sgivc=yes],, +# [#include ]) +# +# # if that succeeded, then check for the -lXsgivc +# if test "$have_sgivc" = yes; then +# have_sgivc=no +# AC_CHECK_X_LIB(Xsgivc, XSGIvcQueryGammaMap, +# [have_sgivc=yes; SAVER_LIBS="$SAVER_LIBS -lXsgivc"], [true], +# -lXext -lX11) +# fi +# +# # if that succeeded, then we've really got it. +# if test "$have_sgivc" = yes; then +# AC_DEFINE(HAVE_SGI_VC_EXTENSION) +# fi +# +#elif test "$with_sgivc" != no; then +# echo "error: must be yes or no: --with-sgivc-ext=$with_sgivc" +# exit 1 +#fi + + +############################################################################### +# +# Check for the DPMS server extension. +# +############################################################################### + +have_dpms=no +with_dpms_req=unspecified + +# Check whether --with-dpms-ext was given. +if test "${with_dpms_ext+set}" = set; then : + withval=$with_dpms_ext; with_dpms="$withval"; with_dpms_req="$withval" +else + with_dpms=yes +fi + + + + case "$with_dpms" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DPMS headers" >&5 +$as_echo_n "checking for DPMS headers... " >&6; } + d=$with_dpms/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DPMS libs" >&5 +$as_echo_n "checking for DPMS libs... " >&6; } + d=$with_dpms/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_dpms_req="yes" + with_dpms=$with_dpms_req + ;; + + *) + echo "" + echo "error: argument to --with-dpms-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_dpms" = yes; then + + # first check for dpms.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/dpms.h" "ac_cv_header_X11_extensions_dpms_h" "#include + #include +" +if test "x$ac_cv_header_X11_extensions_dpms_h" = xyes; then : + have_dpms=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the DPMS code in the libraries + if test "$have_dpms" = yes; then + + # first look in -lXext (this is where it is with XFree86 4.0) + have_dpms=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DPMSInfo in -lXext" >&5 +$as_echo_n "checking for DPMSInfo in -lXext... " >&6; } +if ${ac_cv_lib_Xext_DPMSInfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXext -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char DPMSInfo (); +int +main () +{ +return DPMSInfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xext_DPMSInfo=yes +else + ac_cv_lib_Xext_DPMSInfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_DPMSInfo" >&5 +$as_echo "$ac_cv_lib_Xext_DPMSInfo" >&6; } +if test "x$ac_cv_lib_Xext_DPMSInfo" = xyes; then : + have_dpms=yes +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + # if that failed, look in -lXdpms (this is where it was in XFree86 3.x) + if test "$have_dpms" = no; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DPMSInfo in -lXdpms" >&5 +$as_echo_n "checking for DPMSInfo in -lXdpms... " >&6; } +if ${ac_cv_lib_Xdpms_DPMSInfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXdpms -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char DPMSInfo (); +int +main () +{ +return DPMSInfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xdpms_DPMSInfo=yes +else + ac_cv_lib_Xdpms_DPMSInfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xdpms_DPMSInfo" >&5 +$as_echo "$ac_cv_lib_Xdpms_DPMSInfo" >&6; } +if test "x$ac_cv_lib_Xdpms_DPMSInfo" = xyes; then : + have_dpms=yes; XDPMS_LIBS="-lXdpms" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + fi + + + # if that succeeded, then we've really got it. + if test "$have_dpms" = yes; then + $as_echo "#define HAVE_DPMS_EXTENSION 1" >>confdefs.h + + fi + +elif test "$with_dpms" != no; then + echo "error: must be yes or no: --with-dpms-ext=$with_dpms" + exit 1 +fi + + +############################################################################### +# +# Check for the XINERAMA server extension. +# +############################################################################### + +have_xinerama=no +with_xinerama_req=unspecified + +# Check whether --with-xinerama-ext was given. +if test "${with_xinerama_ext+set}" = set; then : + withval=$with_xinerama_ext; with_xinerama="$withval"; with_xinerama_req="$withval" +else + with_xinerama=yes +fi + + + + case "$with_xinerama" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XINERAMA headers" >&5 +$as_echo_n "checking for XINERAMA headers... " >&6; } + d=$with_xinerama/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XINERAMA libs" >&5 +$as_echo_n "checking for XINERAMA libs... " >&6; } + d=$with_xinerama/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xinerama_req="yes" + with_xinerama=$with_xinerama_req + ;; + + *) + echo "" + echo "error: argument to --with-xinerama-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xinerama" = yes; then + + # first check for Xinerama.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xinerama.h" "ac_cv_header_X11_extensions_Xinerama_h" "#include +" +if test "x$ac_cv_header_X11_extensions_Xinerama_h" = xyes; then : + have_xinerama=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the XINERAMA code in the libraries + if test "$have_xinerama" = yes; then + + # first look in -lXext + have_xinerama=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryScreens in -lXext" >&5 +$as_echo_n "checking for XineramaQueryScreens in -lXext... " >&6; } +if ${ac_cv_lib_Xext_XineramaQueryScreens+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXext -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XineramaQueryScreens (); +int +main () +{ +return XineramaQueryScreens (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xext_XineramaQueryScreens=yes +else + ac_cv_lib_Xext_XineramaQueryScreens=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XineramaQueryScreens" >&5 +$as_echo "$ac_cv_lib_Xext_XineramaQueryScreens" >&6; } +if test "x$ac_cv_lib_Xext_XineramaQueryScreens" = xyes; then : + have_xinerama=yes +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + # if that failed, look in -lXinerama (this is where it is in XFree86 4.1.) + if test "$have_xinerama" = no; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryScreens in -lXinerama" >&5 +$as_echo_n "checking for XineramaQueryScreens in -lXinerama... " >&6; } +if ${ac_cv_lib_Xinerama_XineramaQueryScreens+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXinerama -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XineramaQueryScreens (); +int +main () +{ +return XineramaQueryScreens (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xinerama_XineramaQueryScreens=yes +else + ac_cv_lib_Xinerama_XineramaQueryScreens=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xinerama_XineramaQueryScreens" >&5 +$as_echo "$ac_cv_lib_Xinerama_XineramaQueryScreens" >&6; } +if test "x$ac_cv_lib_Xinerama_XineramaQueryScreens" = xyes; then : + have_xinerama=yes; XINERAMA_LIBS="-lXinerama" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + fi + + # if that succeeded, then we've really got it. + if test "$have_xinerama" = yes; then + $as_echo "#define HAVE_XINERAMA 1" >>confdefs.h + + fi + +elif test "$with_xinerama" != no; then + echo "error: must be yes or no: --with-xinerama-ext=$with_xinerama" + exit 1 +fi + + +############################################################################### +# +# Check for the XINPUT server extension. +# +############################################################################### + +have_xinput=no +with_xinput_req=unspecified + +# Check whether --with-xinput-ext was given. +if test "${with_xinput_ext+set}" = set; then : + withval=$with_xinput_ext; with_xinput="$withval"; with_xinput_req="$withval" +else + with_xinput=yes +fi + + + + case "$with_xinput" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XINPUT headers" >&5 +$as_echo_n "checking for XINPUT headers... " >&6; } + d=$with_xinput/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XINPUT libs" >&5 +$as_echo_n "checking for XINPUT libs... " >&6; } + d=$with_xinput/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xinput_req="yes" + with_xinput=$with_xinput_req + ;; + + *) + echo "" + echo "error: argument to --with-xinput-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xinput" = yes; then + + # first check for Xinput.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/XInput.h" "ac_cv_header_X11_extensions_XInput_h" "#include +" +if test "x$ac_cv_header_X11_extensions_XInput_h" = xyes; then : + have_xinput=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for libXi + if test "$have_xinput" = yes; then + have_xinput=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XListInputDevices in -lXi" >&5 +$as_echo_n "checking for XListInputDevices in -lXi... " >&6; } +if ${ac_cv_lib_Xi_XListInputDevices+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXi -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XListInputDevices (); +int +main () +{ +return XListInputDevices (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xi_XListInputDevices=yes +else + ac_cv_lib_Xi_XListInputDevices=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xi_XListInputDevices" >&5 +$as_echo "$ac_cv_lib_Xi_XListInputDevices" >&6; } +if test "x$ac_cv_lib_Xi_XListInputDevices" = xyes; then : + have_xinput=yes; SAVER_LIBS="$SAVER_LIBS -lXi" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # if that succeeded, then we've really got it. + if test "$have_xinput" = yes; then + $as_echo "#define HAVE_XINPUT 1" >>confdefs.h + + fi + +elif test "$with_xinput" != no; then + echo "error: must be yes or no: --with-xinput-ext=$with_xinput" + exit 1 +fi + + +############################################################################### +# +# Check for the XF86VMODE server extension (for virtual screens.) +# +############################################################################### + +have_xf86vmode=no +with_xf86vmode_req=unspecified + +# Check whether --with-xf86vmode-ext was given. +if test "${with_xf86vmode_ext+set}" = set; then : + withval=$with_xf86vmode_ext; with_xf86vmode="$withval"; with_xf86vmode_req="$withval" +else + with_xf86vmode=yes +fi + + + + case "$with_xf86vmode" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xf86vmode headers" >&5 +$as_echo_n "checking for xf86vmode headers... " >&6; } + d=$with_xf86vmode/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xf86vmode libs" >&5 +$as_echo_n "checking for xf86vmode libs... " >&6; } + d=$with_xf86vmode/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xf86vmode_req="yes" + with_xf86vmode=$with_xf86vmode_req + ;; + + *) + echo "" + echo "error: argument to --with-xf86vmode-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +VIDMODE_LIBS="" + +if test "$with_xf86vmode" = yes; then + + # first check for xf86vmode.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/xf86vmode.h" "ac_cv_header_X11_extensions_xf86vmode_h" "#include +" +if test "x$ac_cv_header_X11_extensions_xf86vmode_h" = xyes; then : + have_xf86vmode=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the -lXxf86vm + if test "$have_xf86vmode" = yes; then + have_xf86vmode=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XF86VidModeGetViewPort in -lXxf86vm" >&5 +$as_echo_n "checking for XF86VidModeGetViewPort in -lXxf86vm... " >&6; } +if ${ac_cv_lib_Xxf86vm_XF86VidModeGetViewPort+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXxf86vm -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XF86VidModeGetViewPort (); +int +main () +{ +return XF86VidModeGetViewPort (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xxf86vm_XF86VidModeGetViewPort=yes +else + ac_cv_lib_Xxf86vm_XF86VidModeGetViewPort=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xxf86vm_XF86VidModeGetViewPort" >&5 +$as_echo "$ac_cv_lib_Xxf86vm_XF86VidModeGetViewPort" >&6; } +if test "x$ac_cv_lib_Xxf86vm_XF86VidModeGetViewPort" = xyes; then : + have_xf86vmode=yes; + VIDMODE_LIBS="-lXxf86vm"; + SAVER_LIBS="$SAVER_LIBS $VIDMODE_LIBS" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # if that succeeded, then we've really got it. + if test "$have_xf86vmode" = yes; then + $as_echo "#define HAVE_XF86VMODE 1" >>confdefs.h + + fi + +elif test "$with_xf86vmode" != no; then + echo "error: must be yes or no: --with-xf86vmode-ext=$with_xf86vmode" + exit 1 +fi + + +############################################################################### +# +# Check for the XF86VMODE server extension (for gamma fading.) +# +############################################################################### + +have_xf86gamma=no +have_xf86gamma_ramp=no +with_xf86gamma_req=unspecified + +# Check whether --with-xf86gamma-ext was given. +if test "${with_xf86gamma_ext+set}" = set; then : + withval=$with_xf86gamma_ext; with_xf86gamma="$withval"; with_xf86gamma_req="$withval" +else + with_xf86gamma=yes +fi + + + + case "$with_xf86gamma" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xf86gamma headers" >&5 +$as_echo_n "checking for xf86gamma headers... " >&6; } + d=$with_xf86gamma/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xf86gamma libs" >&5 +$as_echo_n "checking for xf86gamma libs... " >&6; } + d=$with_xf86gamma/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xf86gamma_req="yes" + with_xf86gamma=$with_xf86gamma_req + ;; + + *) + echo "" + echo "error: argument to --with-xf86gamma-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xf86gamma" = yes; then + + # first check for xf86vmode.h, if we haven't already + if test "$have_xf86vmode" = yes; then + have_xf86gamma=yes + else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/xf86vmode.h" "ac_cv_header_X11_extensions_xf86vmode_h" "#include +" +if test "x$ac_cv_header_X11_extensions_xf86vmode_h" = xyes; then : + have_xf86gamma=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + # if that succeeded, then check for the -lXxf86vm + if test "$have_xf86gamma" = yes; then + have_xf86gamma=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XF86VidModeSetGamma in -lXxf86vm" >&5 +$as_echo_n "checking for XF86VidModeSetGamma in -lXxf86vm... " >&6; } +if ${ac_cv_lib_Xxf86vm_XF86VidModeSetGamma+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXxf86vm -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XF86VidModeSetGamma (); +int +main () +{ +return XF86VidModeSetGamma (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xxf86vm_XF86VidModeSetGamma=yes +else + ac_cv_lib_Xxf86vm_XF86VidModeSetGamma=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xxf86vm_XF86VidModeSetGamma" >&5 +$as_echo "$ac_cv_lib_Xxf86vm_XF86VidModeSetGamma" >&6; } +if test "x$ac_cv_lib_Xxf86vm_XF86VidModeSetGamma" = xyes; then : + have_xf86gamma=yes +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # check for the Ramp versions of the functions too. + if test "$have_xf86gamma" = yes; then + have_xf86gamma_ramp=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XF86VidModeSetGammaRamp in -lXxf86vm" >&5 +$as_echo_n "checking for XF86VidModeSetGammaRamp in -lXxf86vm... " >&6; } +if ${ac_cv_lib_Xxf86vm_XF86VidModeSetGammaRamp+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXxf86vm -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XF86VidModeSetGammaRamp (); +int +main () +{ +return XF86VidModeSetGammaRamp (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xxf86vm_XF86VidModeSetGammaRamp=yes +else + ac_cv_lib_Xxf86vm_XF86VidModeSetGammaRamp=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xxf86vm_XF86VidModeSetGammaRamp" >&5 +$as_echo "$ac_cv_lib_Xxf86vm_XF86VidModeSetGammaRamp" >&6; } +if test "x$ac_cv_lib_Xxf86vm_XF86VidModeSetGammaRamp" = xyes; then : + have_xf86gamma_ramp=yes +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + # if those tests succeeded, then we've really got the functions. + if test "$have_xf86gamma" = yes; then + $as_echo "#define HAVE_XF86VMODE_GAMMA 1" >>confdefs.h + + fi + + if test "$have_xf86gamma_ramp" = yes; then + $as_echo "#define HAVE_XF86VMODE_GAMMA_RAMP 1" >>confdefs.h + + fi + + # pull in the lib, if we haven't already + if test "$have_xf86gamma" = yes -a "$have_xf86vmode" = no; then + SAVER_LIBS="$SAVER_LIBS -lXxf86vm" + fi + +elif test "$with_xf86gamma" != no; then + echo "error: must be yes or no: --with-xf86gamma-ext=$with_xf86vmode" + exit 1 +fi + + +############################################################################### +# +# Check for the RANDR (Resize and Rotate) server extension. +# +# We need this to detect when the resolution of the desktop +# has changed out from under us (this is a newer, different +# mechanism than the XF86VMODE virtual viewports.) +# +############################################################################### + +have_randr=no +with_randr_req=unspecified + +# Check whether --with-randr-ext was given. +if test "${with_randr_ext+set}" = set; then : + withval=$with_randr_ext; with_randr="$withval"; with_randr_req="$withval" +else + with_randr=yes +fi + + + + case "$with_randr" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RANDR headers" >&5 +$as_echo_n "checking for RANDR headers... " >&6; } + d=$with_randr/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RANDR libs" >&5 +$as_echo_n "checking for RANDR libs... " >&6; } + d=$with_randr/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_randr_req="yes" + with_randr=$with_randr_req + ;; + + *) + echo "" + echo "error: argument to --with-randr-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_randr" = yes; then + + # first check for Xrandr.h + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xrandr.h" "ac_cv_header_X11_extensions_Xrandr_h" "#include +" +if test "x$ac_cv_header_X11_extensions_Xrandr_h" = xyes; then : + have_randr=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for the XRR code in the libraries + if test "$have_randr" = yes; then + + # RANDR probably needs -lXrender + xrender_libs= + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRenderSetSubpixelOrder in -lXrender" >&5 +$as_echo_n "checking for XRenderSetSubpixelOrder in -lXrender... " >&6; } +if ${ac_cv_lib_Xrender_XRenderSetSubpixelOrder+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXrender -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XRenderSetSubpixelOrder (); +int +main () +{ +return XRenderSetSubpixelOrder (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xrender_XRenderSetSubpixelOrder=yes +else + ac_cv_lib_Xrender_XRenderSetSubpixelOrder=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xrender_XRenderSetSubpixelOrder" >&5 +$as_echo "$ac_cv_lib_Xrender_XRenderSetSubpixelOrder" >&6; } +if test "x$ac_cv_lib_Xrender_XRenderSetSubpixelOrder" = xyes; then : + xrender_libs="-lXrender" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + # first look for RANDR in -lXext + have_randr=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRGetScreenInfo in -lXext" >&5 +$as_echo_n "checking for XRRGetScreenInfo in -lXext... " >&6; } +if ${ac_cv_lib_Xext_XRRGetScreenInfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXext $xrender_libs -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XRRGetScreenInfo (); +int +main () +{ +return XRRGetScreenInfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xext_XRRGetScreenInfo=yes +else + ac_cv_lib_Xext_XRRGetScreenInfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XRRGetScreenInfo" >&5 +$as_echo "$ac_cv_lib_Xext_XRRGetScreenInfo" >&6; } +if test "x$ac_cv_lib_Xext_XRRGetScreenInfo" = xyes; then : + have_randr=yes; SAVER_LIBS="$SAVER_LIBS $xrender_libs" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + # if that failed, look in -lXrandr + if test "$have_randr" = no; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRGetScreenInfo in -lXrandr" >&5 +$as_echo_n "checking for XRRGetScreenInfo in -lXrandr... " >&6; } +if ${ac_cv_lib_Xrandr_XRRGetScreenInfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXrandr $xrender_libs -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XRRGetScreenInfo (); +int +main () +{ +return XRRGetScreenInfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xrandr_XRRGetScreenInfo=yes +else + ac_cv_lib_Xrandr_XRRGetScreenInfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xrandr_XRRGetScreenInfo" >&5 +$as_echo "$ac_cv_lib_Xrandr_XRRGetScreenInfo" >&6; } +if test "x$ac_cv_lib_Xrandr_XRRGetScreenInfo" = xyes; then : + have_randr=yes; SAVER_LIBS="$SAVER_LIBS -lXrandr $xrender_libs" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + fi + + # if that succeeded, then we've really got it. + if test "$have_randr" = yes; then + $as_echo "#define HAVE_RANDR 1" >>confdefs.h + + + # Now check for version 1.2 in the same libs. + # Try to compile, since on MacOS 10.5.7, headers are older than libs! + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRGetScreenResources" >&5 +$as_echo_n "checking for XRRGetScreenResources... " >&6; } +if ${ac_cv_randr_12+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_randr_12=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include +int +main () +{ +XRRScreenResources *res = + XRRGetScreenResources (0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_randr_12=yes +else + ac_cv_randr_12=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_randr_12" >&5 +$as_echo "$ac_cv_randr_12" >&6; } + if test "$ac_cv_randr_12" = yes ; then + $as_echo "#define HAVE_RANDR_12 1" >>confdefs.h + + fi +# AC_CHECK_X_LIB(c, XRRGetOutputInfo, [AC_DEFINE(HAVE_RANDR_12)], +# [true], $SAVER_LIBS) + fi + + +elif test "$with_randr" != no; then + echo "error: must be yes or no: --with-randr-ext=$with_randr" + exit 1 +fi + + +############################################################################### +# +# Check for XF86MiscSetGrabKeysState (but only bother if we are already +# using other XF86 stuff.) +# +############################################################################### + +have_xf86miscsetgrabkeysstate=no +if test "$have_xf86gamma" = yes -o "$have_xf86vmode" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XF86MiscSetGrabKeysState in -lXxf86misc" >&5 +$as_echo_n "checking for XF86MiscSetGrabKeysState in -lXxf86misc... " >&6; } +if ${ac_cv_lib_Xxf86misc_XF86MiscSetGrabKeysState+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXxf86misc -lXext -lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XF86MiscSetGrabKeysState (); +int +main () +{ +return XF86MiscSetGrabKeysState (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xxf86misc_XF86MiscSetGrabKeysState=yes +else + ac_cv_lib_Xxf86misc_XF86MiscSetGrabKeysState=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xxf86misc_XF86MiscSetGrabKeysState" >&5 +$as_echo "$ac_cv_lib_Xxf86misc_XF86MiscSetGrabKeysState" >&6; } +if test "x$ac_cv_lib_Xxf86misc_XF86MiscSetGrabKeysState" = xyes; then : + have_xf86miscsetgrabkeysstate=yes +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + if test "$have_xf86miscsetgrabkeysstate" = yes ; then + SAVER_LIBS="$SAVER_LIBS -lXxf86misc" + $as_echo "#define HAVE_XF86MISCSETGRABKEYSSTATE 1" >>confdefs.h + + fi +fi + + +############################################################################### +# +# Check for HP XHPDisableReset and XHPEnableReset. +# +############################################################################### + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XHPDisableReset in X11/XHPlib.h" >&5 +$as_echo_n "checking for XHPDisableReset in X11/XHPlib.h... " >&6; } + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "XHPDisableReset" >/dev/null 2>&1; then : + $as_echo "#define HAVE_XHPDISABLERESET 1" >>confdefs.h + + SAVER_LIBS="-lXhp11 $SAVER_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -rf conftest* + + CPPFLAGS="$ac_save_CPPFLAGS" + + +############################################################################### +# +# Check for /proc/interrupts. +# +############################################################################### + +have_proc_interrupts=no +with_proc_interrupts_req=unspecified + +# Check whether --with-proc-interrupts was given. +if test "${with_proc_interrupts+set}" = set; then : + withval=$with_proc_interrupts; with_proc_interrupts="$withval"; with_proc_interrupts_req="$withval" +else + with_proc_interrupts=yes +fi + + +if test "$with_proc_interrupts" = yes; then + + # Note that we may be building in an environment (e.g. Debian buildd chroot) + # without a proper /proc filesystem. If /proc/interrupts exists, then we'll + # check that it has the bits we need, but otherwise we'll just go on faith. + # + have_proc_interrupts=yes + + if test -f /proc/interrupts; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether /proc/interrupts contains keyboard data" >&5 +$as_echo_n "checking whether /proc/interrupts contains keyboard data... " >&6; } +if ${ac_cv_have_proc_interrupts+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_have_proc_interrupts=no + if grep 'keyboard\|i8042' /proc/interrupts >/dev/null 2>&1 ; then + ac_cv_have_proc_interrupts=yes + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_proc_interrupts" >&5 +$as_echo "$ac_cv_have_proc_interrupts" >&6; } + have_proc_interrupts=$ac_cv_have_proc_interrupts + fi + + if test "$have_proc_interrupts" = yes; then + $as_echo "#define HAVE_PROC_INTERRUPTS 1" >>confdefs.h + + fi + +elif test "$with_proc_interrupts" != no; then + echo "error: must be yes or no: --with-proc-interrupts=$with_proc_interrupts" + exit 1 +fi + + +############################################################################### +# +# The --enable-locking option +# +############################################################################### + +# Check whether --enable-locking was given. +if test "${enable_locking+set}" = set; then : + enableval=$enable_locking; enable_locking="$enableval" +else + if test "$ac_macosx" = yes; then + # We can't lock on MacOS X, so default to not compiling in support for it. + # But allow --enable-locking to override that, so I can debug Linux locking + # under MacOS X11. + enable_locking=no + else + enable_locking=yes + fi +fi + +if test "$enable_locking" = yes; then + true +elif test "$enable_locking" = no; then + $as_echo "#define NO_LOCKING 1" >>confdefs.h + +else + echo "error: must be yes or no: --enable-locking=$enable_locking" + exit 1 +fi + + +############################################################################### +# +# Whether to allow root password to unblank. +# +############################################################################### +# Check whether --enable-root-passwd was given. +if test "${enable_root_passwd+set}" = set; then : + enableval=$enable_root_passwd; enable_root_passwd="$enableval" +else + enable_root_passwd=yes +fi + +if test "$enable_root_passwd" = yes; then + $as_echo "#define ALLOW_ROOT_PASSWD 1" >>confdefs.h + + true +elif test "$enable_root_passwd" != no; then + echo "error: must be yes or no: --enable-root-passwd=$enable_root_passwd" + exit 1 +fi + +############################################################################### +# +# Check for PAM. +# +############################################################################### + +case "$host" in + *-solaris*) + # Solaris systems tend to come with PAM misconfigured. + # Don't build it by default, even if the headers exist. + with_pam_default=no + ;; + *) + # Default to building PAM support on all other systems, if it exists. + with_pam_default=yes + ;; +esac + +have_pam=no +with_pam_req=unspecified + + +# Check whether --with-pam was given. +if test "${with_pam+set}" = set; then : + withval=$with_pam; with_pam="$withval"; with_pam_req="$withval" +else + with_pam=$with_pam_default +fi + + + +# Check whether --with-pam_service_name was given. +if test "${with_pam_service_name+set}" = set; then : + withval=$with_pam_service_name; pam_service_name="$withval" +else + pam_service_name="xscreensaver" +fi + + +# Check whether --enable-pam-check-account-type was given. +if test "${enable_pam_check_account_type+set}" = set; then : + enableval=$enable_pam_check_account_type; enable_pam_check_account_type="$enableval" +else + enable_pam_check_account_type=no +fi + +if test "$enable_pam_check_account_type" = yes ; then + $as_echo "#define PAM_CHECK_ACCOUNT_TYPE 1" >>confdefs.h + + true +elif test "$enable_pam_check_account_type" != no ; then + echo "error: must be yes or no: --enable-pam-check-account-type=$enable_pam_check_account_type" + exit 1 +fi + + + case "$with_pam" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PAM headers" >&5 +$as_echo_n "checking for PAM headers... " >&6; } + d=$with_pam/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PAM libs" >&5 +$as_echo_n "checking for PAM libs... " >&6; } + d=$with_pam/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_pam_req="yes" + with_pam=$with_pam_req + ;; + + *) + echo "" + echo "error: argument to --with-pam must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$enable_locking" = yes -a "$with_pam" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PAM" >&5 +$as_echo_n "checking for PAM... " >&6; } +if ${ac_cv_pam+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_pam=yes +else + ac_cv_pam=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pam" >&5 +$as_echo "$ac_cv_pam" >&6; } + if test "$ac_cv_pam" = yes ; then + have_pam=yes + $as_echo "#define HAVE_PAM 1" >>confdefs.h + + cat >>confdefs.h <<_ACEOF +#define PAM_SERVICE_NAME "$pam_service_name" +_ACEOF + + + PASSWD_LIBS="${PASSWD_LIBS} -lpam" + + # libpam typically requires dlopen and dlsym. On FreeBSD, + # those are in libc. On Linux and Solaris, they're in libdl. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + PASSWD_LIBS="${PASSWD_LIBS} -ldl" +fi + + + # On Linux, sigtimedwait() is in libc; on Solaris, it's in librt. + have_timedwait=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigtimedwait in -lc" >&5 +$as_echo_n "checking for sigtimedwait in -lc... " >&6; } +if ${ac_cv_lib_c_sigtimedwait+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sigtimedwait (); +int +main () +{ +return sigtimedwait (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_sigtimedwait=yes +else + ac_cv_lib_c_sigtimedwait=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_sigtimedwait" >&5 +$as_echo "$ac_cv_lib_c_sigtimedwait" >&6; } +if test "x$ac_cv_lib_c_sigtimedwait" = xyes; then : + have_timedwait=yes + $as_echo "#define HAVE_SIGTIMEDWAIT 1" >>confdefs.h + +fi + + if test "$have_timedwait" = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigtimedwait in -lrt" >&5 +$as_echo_n "checking for sigtimedwait in -lrt... " >&6; } +if ${ac_cv_lib_rt_sigtimedwait+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sigtimedwait (); +int +main () +{ +return sigtimedwait (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_rt_sigtimedwait=yes +else + ac_cv_lib_rt_sigtimedwait=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_sigtimedwait" >&5 +$as_echo "$ac_cv_lib_rt_sigtimedwait" >&6; } +if test "x$ac_cv_lib_rt_sigtimedwait" = xyes; then : + have_timedwait=yes + $as_echo "#define HAVE_SIGTIMEDWAIT 1" >>confdefs.h + + PASSWD_LIBS="${PASSWD_LIBS} -lrt" +fi + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to call pam_strerror" >&5 +$as_echo_n "checking how to call pam_strerror... " >&6; } + if ${ac_cv_pam_strerror_args+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include +int +main () +{ +pam_handle_t *pamh = 0; + char *s = pam_strerror(pamh, PAM_SUCCESS); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_pam_strerror_args=2 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include +int +main () +{ +char *s = + pam_strerror(PAM_SUCCESS); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_pam_strerror_args=1 +else + ac_pam_strerror_args=0 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" + ac_cv_pam_strerror_args=$ac_pam_strerror_args +fi + + ac_pam_strerror_args=$ac_cv_pam_strerror_args + if test "$ac_pam_strerror_args" = 1 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: one argument" >&5 +$as_echo "one argument" >&6; } + elif test "$ac_pam_strerror_args" = 2 ; then + $as_echo "#define PAM_STRERROR_TWO_ARGS 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: two arguments" >&5 +$as_echo "two arguments" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 +$as_echo "unknown" >&6; } + fi + +# Check pam_fail_delay + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pam_fail_delay in -lpam" >&5 +$as_echo_n "checking pam_fail_delay in -lpam... " >&6; } + if ${ac_cv_pam_fail_delay+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="-lpam" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pam_handle_t *pamh = 0; + unsigned int usec = 1; + int status = pam_fail_delay (pamh, usec); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_pam_fail_delay=yes +else + ac_pam_fail_delay=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_cv_pam_fail_delay=$ac_pam_fail_delay, + LDFLAGS=$ac_save_LDFLAGS +fi + + + if test "$ac_pam_fail_delay" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + $as_echo "#define HAVE_PAM_FAIL_DELAY 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + fi +fi + + +############################################################################### +# +# Check for Kerberos. +# +############################################################################### + +have_kerberos=no +have_kerberos5=no +with_kerberos_req=unspecified + + +# Check whether --with-kerberos was given. +if test "${with_kerberos+set}" = set; then : + withval=$with_kerberos; with_kerberos="$withval"; with_kerberos_req="$withval" +else + with_kerberos=yes +fi + + + + case "$with_kerberos" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Kerberos headers" >&5 +$as_echo_n "checking for Kerberos headers... " >&6; } + d=$with_kerberos/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Kerberos libs" >&5 +$as_echo_n "checking for Kerberos libs... " >&6; } + d=$with_kerberos/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_kerberos_req="yes" + with_kerberos=$with_kerberos_req + ;; + + *) + echo "" + echo "error: argument to --with-kerberos must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$enable_locking" = yes -a "$with_kerberos" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Kerberos 4" >&5 +$as_echo_n "checking for Kerberos 4... " >&6; } +if ${ac_cv_kerberos+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_kerberos=yes +else + ac_cv_kerberos=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kerberos" >&5 +$as_echo "$ac_cv_kerberos" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Kerberos 5" >&5 +$as_echo_n "checking for Kerberos 5... " >&6; } +if ${ac_cv_kerberos5+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_kerberos5=yes +else + ac_cv_kerberos5=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kerberos5" >&5 +$as_echo "$ac_cv_kerberos5" >&6; } + + if test "$ac_cv_kerberos" = yes ; then + have_kerberos=yes + $as_echo "#define HAVE_KERBEROS 1" >>confdefs.h + + fi + + if test "$ac_cv_kerberos5" = yes ; then + + # Andrew Snare wrote: + # + # You were assuming that if kerberosV (krb5) was found, then kerberosIV + # (krb4) was also available. This turns out not to be the case with + # mit-krb-1.2.7; apparently backwards-compatibility with KerberosIV + # is optional. + # + # So, disable kerberosV support if libkrb4 can't be found. + # This is not the best solution, but it makes the compile not fail. + # + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb_get_tf_realm in -lkrb4" >&5 +$as_echo_n "checking for krb_get_tf_realm in -lkrb4... " >&6; } +if ${ac_cv_lib_krb4_krb_get_tf_realm+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkrb4 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char krb_get_tf_realm (); +int +main () +{ +return krb_get_tf_realm (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_krb4_krb_get_tf_realm=yes +else + ac_cv_lib_krb4_krb_get_tf_realm=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_krb4_krb_get_tf_realm" >&5 +$as_echo "$ac_cv_lib_krb4_krb_get_tf_realm" >&6; } +if test "x$ac_cv_lib_krb4_krb_get_tf_realm" = xyes; then : + have_kerberos=yes +else + have_kerberos=no +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + if test "$have_kerberos" = yes ; then + have_kerberos5=yes + $as_echo "#define HAVE_KERBEROS 1" >>confdefs.h + + $as_echo "#define HAVE_KERBEROS5 1" >>confdefs.h + + else + have_kerberos5=no + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find compat lib (libkrb4) needed to use Kerberos 5" >&5 +$as_echo "$as_me: WARNING: Cannot find compat lib (libkrb4) needed to use Kerberos 5" >&2;} + fi + + fi + + if test "$have_kerberos5" = yes ; then + # from Matt Knopp + # (who got it from amu@mit.edu) + + PASSWD_LIBS="$PASSWD_LIBS -lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err" + + # jwz: MacOS X uses -lkrb5, but not -lcrypt + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 +$as_echo_n "checking for crypt in -lcrypt... " >&6; } +if ${ac_cv_lib_crypt_crypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypt_crypt=yes +else + ac_cv_lib_crypt_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 +$as_echo "$ac_cv_lib_crypt_crypt" >&6; } +if test "x$ac_cv_lib_crypt_crypt" = xyes; then : + PASSWD_LIBS="$PASSWD_LIBS -lcrypt" +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + + elif test "$have_kerberos" = yes ; then + # from Tim Showalter for FreeBSD 4.2 + PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes -lcom_err" + fi + + if test "$have_kerberos" = yes ; then + ac_fn_c_check_func "$LINENO" "res_search" "ac_cv_func_res_search" +if test "x$ac_cv_func_res_search" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_search in -lresolv" >&5 +$as_echo_n "checking for res_search in -lresolv... " >&6; } +if ${ac_cv_lib_resolv_res_search+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char res_search (); +int +main () +{ +return res_search (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_resolv_res_search=yes +else + ac_cv_lib_resolv_res_search=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_res_search" >&5 +$as_echo "$ac_cv_lib_resolv_res_search" >&6; } +if test "x$ac_cv_lib_resolv_res_search" = xyes; then : + PASSWD_LIBS="${PASSWD_LIBS} -lresolv" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find DNS resolver libraries needed for Kerberos" >&5 +$as_echo "$as_me: WARNING: Can't find DNS resolver libraries needed for Kerberos" >&2;} + +fi + +fi + + fi +fi + + +############################################################################### +# +# Check for the nine billion variants of shadow passwords... +# +############################################################################### + +need_setuid=no + +have_shadow=no +with_shadow_req=unspecified + + +# Check whether --with-shadow was given. +if test "${with_shadow+set}" = set; then : + withval=$with_shadow; with_shadow="$withval"; with_shadow_req="$withval" +else + with_shadow=yes +fi + + + + case "$with_shadow" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shadow password headers" >&5 +$as_echo_n "checking for shadow password headers... " >&6; } + d=$with_shadow/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shadow password libs" >&5 +$as_echo_n "checking for shadow password libs... " >&6; } + d=$with_shadow/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_shadow_req="yes" + with_shadow=$with_shadow_req + ;; + + *) + echo "" + echo "error: argument to --with-shadow must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$enable_locking" = no ; then + with_shadow_req=no + with_shadow=no +fi + + +############################################################################### +# +# Check for Sun "adjunct" passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Sun-style shadow passwords" >&5 +$as_echo_n "checking for Sun-style shadow passwords... " >&6; } +if ${ac_cv_sun_adjunct+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include + #include + #include +int +main () +{ +struct passwd_adjunct *p = getpwanam("nobody"); + const char *pw = p->pwa_passwd; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sun_adjunct=yes +else + ac_cv_sun_adjunct=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sun_adjunct" >&5 +$as_echo "$ac_cv_sun_adjunct" >&6; } + if test "$ac_cv_sun_adjunct" = yes; then + have_shadow_adjunct=yes + have_shadow=yes + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for DEC and SCO so-called "enhanced" security. +# +############################################################################### + +if test "$with_shadow" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEC-style shadow passwords" >&5 +$as_echo_n "checking for DEC-style shadow passwords... " >&6; } +if ${ac_cv_enhanced_passwd+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include + #include + #include +int +main () +{ +struct pr_passwd *p; + const char *pw; + set_auth_parameters(0, 0); + check_auth_parameters(); + p = getprpwnam("nobody"); + pw = p->ufld.fd_encrypt; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_enhanced_passwd=yes +else + ac_cv_enhanced_passwd=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enhanced_passwd" >&5 +$as_echo "$ac_cv_enhanced_passwd" >&6; } + if test $ac_cv_enhanced_passwd = yes; then + have_shadow_enhanced=yes + have_shadow=yes + need_setuid=yes + + # On SCO, getprpwnam() is in -lprot (which uses nap() from -lx) + # (I'm told it needs -lcurses too, but I don't understand why.) + # But on DEC, it's in -lsecurity. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getprpwnam in -lprot" >&5 +$as_echo_n "checking for getprpwnam in -lprot... " >&6; } +if ${ac_cv_lib_prot_getprpwnam+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lprot -lx $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getprpwnam (); +int +main () +{ +return getprpwnam (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_prot_getprpwnam=yes +else + ac_cv_lib_prot_getprpwnam=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_prot_getprpwnam" >&5 +$as_echo "$ac_cv_lib_prot_getprpwnam" >&6; } +if test "x$ac_cv_lib_prot_getprpwnam" = xyes; then : + PASSWD_LIBS="$PASSWD_LIBS -lprot -lcurses -lx" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getprpwnam in -lsecurity" >&5 +$as_echo_n "checking for getprpwnam in -lsecurity... " >&6; } +if ${ac_cv_lib_security_getprpwnam+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsecurity $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getprpwnam (); +int +main () +{ +return getprpwnam (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_security_getprpwnam=yes +else + ac_cv_lib_security_getprpwnam=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_security_getprpwnam" >&5 +$as_echo "$ac_cv_lib_security_getprpwnam" >&6; } +if test "x$ac_cv_lib_security_getprpwnam" = xyes; then : + PASSWD_LIBS="$PASSWD_LIBS -lsecurity" +fi + +fi + + fi +fi + +############################################################################### +# +# Check for HP's entry in the "Not Invented Here" Sweepstakes. +# +############################################################################### + +if test "$with_shadow" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HP-style shadow passwords" >&5 +$as_echo_n "checking for HP-style shadow passwords... " >&6; } +if ${ac_cv_hpux_passwd+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include + #include + #include +int +main () +{ +struct s_passwd *p = getspwnam("nobody"); + const char *pw = p->pw_passwd; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_hpux_passwd=yes +else + ac_cv_hpux_passwd=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_hpux_passwd" >&5 +$as_echo "$ac_cv_hpux_passwd" >&6; } + if test "$ac_cv_hpux_passwd" = yes; then + have_shadow_hpux=yes + have_shadow=yes + need_setuid=yes + + # on HPUX, bigcrypt is in -lsec + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bigcrypt in -lsec" >&5 +$as_echo_n "checking for bigcrypt in -lsec... " >&6; } +if ${ac_cv_lib_sec_bigcrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsec $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char bigcrypt (); +int +main () +{ +return bigcrypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sec_bigcrypt=yes +else + ac_cv_lib_sec_bigcrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_bigcrypt" >&5 +$as_echo "$ac_cv_lib_sec_bigcrypt" >&6; } +if test "x$ac_cv_lib_sec_bigcrypt" = xyes; then : + PASSWD_LIBS="$PASSWD_LIBS -lsec" +fi + + fi +fi + + +############################################################################### +# +# Check for FreeBSD-style shadow passwords. +# +# On FreeBSD, getpwnam() and friends work just like on non-shadow- +# password systems -- except you only get stuff in the pw_passwd field +# if the running program is setuid. So, guess that we've got this +# lossage to contend with if /etc/master.passwd exists, and default to +# a setuid installation. +# +############################################################################### + +if test "$with_shadow" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeBSD-style shadow passwords" >&5 +$as_echo_n "checking for FreeBSD-style shadow passwords... " >&6; } +if ${ac_cv_master_passwd+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -f /etc/master.passwd ; then + ac_cv_master_passwd=yes + else + ac_cv_master_passwd=no + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_master_passwd" >&5 +$as_echo "$ac_cv_master_passwd" >&6; } + if test "$ac_cv_master_passwd" = yes; then + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for traditional (ha!) shadow passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for generic shadow passwords" >&5 +$as_echo_n "checking for generic shadow passwords... " >&6; } +if ${ac_cv_shadow+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + #include + #include +int +main () +{ +struct spwd *p = getspnam("nobody"); + const char *pw = p->sp_pwdp; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_shadow=yes +else + ac_cv_shadow=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_shadow" >&5 +$as_echo "$ac_cv_shadow" >&6; } + if test "$ac_cv_shadow" = yes; then + have_shadow=yes + need_setuid=yes + + # On some systems (UnixWare 2.1), getspnam() is in -lgen instead of -lc. + have_getspnam=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getspnam in -lc" >&5 +$as_echo_n "checking for getspnam in -lc... " >&6; } +if ${ac_cv_lib_c_getspnam+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getspnam (); +int +main () +{ +return getspnam (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_getspnam=yes +else + ac_cv_lib_c_getspnam=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_getspnam" >&5 +$as_echo "$ac_cv_lib_c_getspnam" >&6; } +if test "x$ac_cv_lib_c_getspnam" = xyes; then : + have_getspnam=yes +fi + + if test "$have_getspnam" = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getspnam in -lgen" >&5 +$as_echo_n "checking for getspnam in -lgen... " >&6; } +if ${ac_cv_lib_gen_getspnam+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgen $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getspnam (); +int +main () +{ +return getspnam (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gen_getspnam=yes +else + ac_cv_lib_gen_getspnam=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_getspnam" >&5 +$as_echo "$ac_cv_lib_gen_getspnam" >&6; } +if test "x$ac_cv_lib_gen_getspnam" = xyes; then : + have_getspnam=yes; PASSWD_LIBS="$PASSWD_LIBS -lgen" +fi + + fi + fi +fi + + +############################################################################### +# +# Check for other libraries needed for non-shadow passwords. +# +############################################################################### + +if test "$enable_locking" = yes ; then + + # On some systems (UnixWare 2.1), crypt() is in -lcrypt instead of -lc. + have_crypt=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lc" >&5 +$as_echo_n "checking for crypt in -lc... " >&6; } +if ${ac_cv_lib_c_crypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_crypt=yes +else + ac_cv_lib_c_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_crypt" >&5 +$as_echo "$ac_cv_lib_c_crypt" >&6; } +if test "x$ac_cv_lib_c_crypt" = xyes; then : + have_crypt=yes +fi + + if test "$have_crypt" = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 +$as_echo_n "checking for crypt in -lcrypt... " >&6; } +if ${ac_cv_lib_crypt_crypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypt_crypt=yes +else + ac_cv_lib_crypt_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 +$as_echo "$ac_cv_lib_crypt_crypt" >&6; } +if test "x$ac_cv_lib_crypt_crypt" = xyes; then : + have_crypt=yes; PASSWD_LIBS="$PASSWD_LIBS -lcrypt" +fi + + fi +fi + + +# Most of the above shadow mechanisms will have set need_setuid to yes, +# if they were found. But, on some systems, we need setuid even when +# using plain old vanilla passwords. +# +if test "$enable_locking" = yes ; then + case "$host" in + *-hpux* | *-aix* | *-netbsd* | *-freebsd* | *-openbsd* ) + need_setuid=yes + ;; + esac +fi + + +if test "$have_shadow_adjunct" = yes ; then + $as_echo "#define HAVE_ADJUNCT_PASSWD 1" >>confdefs.h + +elif test "$have_shadow_enhanced" = yes ; then + $as_echo "#define HAVE_ENHANCED_PASSWD 1" >>confdefs.h + +elif test "$have_shadow_hpux" = yes ; then + $as_echo "#define HAVE_HPUX_PASSWD 1" >>confdefs.h + +elif test "$have_shadow" = yes ; then + $as_echo "#define HAVE_SHADOW_PASSWD 1" >>confdefs.h + +fi + + +############################################################################### +# +# Check for external password helper +# On SuSE, instead of having xscreensaver be a setuid program, they +# fork an external program that takes the password on stdin, and +# returns true if that password is a valid one. Then only that +# smaller program needs to be setuid. +# +# (Note that this external program is not a GUI: the GUI is still +# all in xscreensaver itself; the external program just does auth.) +# +############################################################################### + +have_passwd_helper=no +with_passwd_helper_req=unspecified + + +# Check whether --with-passwd-helper was given. +if test "${with_passwd_helper+set}" = set; then : + withval=$with_passwd_helper; with_passwd_helper="$withval"; with_passwd_helper_req="$withval" +else + with_passwd_helper=no +fi + +# no HANDLE_X_PATH_ARG for this one + +if test "$enable_locking" = no ; then + with_passwd_helper_req=no + with_passwd_helper=no +fi + +case "$with_passwd_helper" in + ""|no) : ;; + /*) + cat >>confdefs.h <<_ACEOF +#define PASSWD_HELPER_PROGRAM "$with_passwd_helper" +_ACEOF + + have_passwd_helper=yes;; + *) + echo "error: --with-passwd-helper needs full pathname of helper (not '$with_passwd_helper')." >&2 + exit 1 +esac + + +############################################################################### +# +# Check for a login manager for a "New Login" button on the lock dialog. +# Usually this will be "/usr/bin/gdmflexiserver". +# +############################################################################### + +with_login_manager_req=unspecified +default_login_manager_1='gdmflexiserver -ls' +default_login_manager_2='kdmctl reserve' + + +# Check whether --with-login-manager was given. +if test "${with_login_manager+set}" = set; then : + withval=$with_login_manager; with_login_manager="$withval"; with_login_manager_req="$withval" +else + with_login_manager=yes +fi + +# no HANDLE_X_PATH_ARG for this one + +if test "$enable_locking" = no ; then + with_login_manager_req=no + with_login_manager=no +fi + +case "$with_login_manager_req" in + no) + with_login_manager="" + ;; + + yes|unspecified) + # Try both defaults, use the one that exists. + + set dummy $default_login_manager_1 ; login_manager_tmp=$2 + unset ac_cv_path_login_manager_tmp # don't cache + # Extract the first word of "$login_manager_tmp", so it can be a program name with args. +set dummy $login_manager_tmp; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_login_manager_tmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $login_manager_tmp in + [\\/]* | ?:[\\/]*) + ac_cv_path_login_manager_tmp="$login_manager_tmp" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_login_manager_tmp="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +login_manager_tmp=$ac_cv_path_login_manager_tmp +if test -n "$login_manager_tmp"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $login_manager_tmp" >&5 +$as_echo "$login_manager_tmp" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test ! -z "$login_manager_tmp" ; then + with_login_manager="$default_login_manager_1" + else + set dummy $default_login_manager_2 ; login_manager_tmp=$2 + unset ac_cv_path_login_manager_tmp # don't cache + # Extract the first word of "$login_manager_tmp", so it can be a program name with args. +set dummy $login_manager_tmp; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_login_manager_tmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $login_manager_tmp in + [\\/]* | ?:[\\/]*) + ac_cv_path_login_manager_tmp="$login_manager_tmp" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_login_manager_tmp="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +login_manager_tmp=$ac_cv_path_login_manager_tmp +if test -n "$login_manager_tmp"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $login_manager_tmp" >&5 +$as_echo "$login_manager_tmp" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test ! -z "$login_manager_tmp" ; then + with_login_manager="$default_login_manager_2" + else + with_login_manager="" + fi + fi + ;; + + /*) + # absolute path specified on cmd line + set dummy $with_login_manager_req ; login_manager_tmp=$2 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $login_manager_tmp" >&5 +$as_echo_n "checking for $login_manager_tmp... " >&6; } + if test -x "$login_manager_tmp" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + with_login_manager="" + fi + ;; + + *) + # relative path specified on cmd line + set dummy $with_login_manager_req ; login_manager_tmp=$2 + unset ac_cv_path_login_manager_tmp # don't cache + # Extract the first word of "$login_manager_tmp", so it can be a program name with args. +set dummy $login_manager_tmp; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_login_manager_tmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $login_manager_tmp in + [\\/]* | ?:[\\/]*) + ac_cv_path_login_manager_tmp="$login_manager_tmp" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_login_manager_tmp="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +login_manager_tmp=$ac_cv_path_login_manager_tmp +if test -n "$login_manager_tmp"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $login_manager_tmp" >&5 +$as_echo "$login_manager_tmp" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test -z "$login_manager_tmp" ; then + with_login_manager="" + else + with_login_manager="$login_manager_tmp" + fi + ;; +esac +ac_cv_login_manager_program="$with_login_manager" + +NEW_LOGIN_COMMAND_P='' +NEW_LOGIN_COMMAND="$ac_cv_login_manager_program" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for login manager" >&5 +$as_echo_n "checking for login manager... " >&6; } +if test -z "$NEW_LOGIN_COMMAND" ; then + NEW_LOGIN_COMMAND="$default_login_manager_1" + NEW_LOGIN_COMMAND_P='! ' + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NEW_LOGIN_COMMAND (disabled)" >&5 +$as_echo "$NEW_LOGIN_COMMAND (disabled)" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NEW_LOGIN_COMMAND" >&5 +$as_echo "$NEW_LOGIN_COMMAND" >&6; } +fi + + +############################################################################### +# +# Check for -lgtk (and Gnome stuff) +# +############################################################################### + +have_gtk=no +with_gtk_req=unspecified + +# Check whether --with-gtk was given. +if test "${with_gtk+set}" = set; then : + withval=$with_gtk; with_gtk="$withval"; with_gtk_req="$withval" +else + with_gtk=yes +fi + + +# if --with-gtk=/directory/ was specified, remember that directory so that +# we can also look for the `gtk-config' program in that directory. +case "$with_gtk" in + /*) + gtk_dir="$with_gtk" + ;; + *) + gtk_dir="" + ;; +esac + + + case "$with_gtk" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Gtk headers" >&5 +$as_echo_n "checking for Gtk headers... " >&6; } + d=$with_gtk/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Gtk libs" >&5 +$as_echo_n "checking for Gtk libs... " >&6; } + d=$with_gtk/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_gtk_req="yes" + with_gtk=$with_gtk_req + ;; + + *) + echo "" + echo "error: argument to --with-gtk must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_gtk" != yes -a "$with_gtk" != no ; then + echo "error: must be yes or no: --with-gtk=$with_gtk" + exit 1 +fi + + +parse_gtk_version_string() { + # M4 sucks!! + + maj=`echo $ac_gtk_version_string | sed -n 's/\..*//p'` + min=`echo $ac_gtk_version_string | sed -n 's/[^.]*\.\([^.]*\).*/\1/p'` + + ac_gtk_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_gtk_version"; then + ac_gtk_version=unknown + ac_gtk_version_string=unknown + fi +} + +# Find pkg-config... (need this for both gtk and gdk_pixbuf.) +# if the user specified --with-gtk=/foo/ then look there. +# +gtk_path="$PATH" +if test ! -z "$gtk_dir"; then + # canonicalize slashes. + foo=`echo "${gtk_dir}/bin" | sed 's@//*@/@g'` + gtk_path="$foo:$gtk_path" +fi + +for ac_prog in pkg-config +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_pkg_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $pkg_config in + [\\/]* | ?:[\\/]*) + ac_cv_path_pkg_config="$pkg_config" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $gtk_path +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_pkg_config="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +pkg_config=$ac_cv_path_pkg_config +if test -n "$pkg_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pkg_config" >&5 +$as_echo "$pkg_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$pkg_config" && break +done + + +if test -z "$pkg_config" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not found!" >&5 +$as_echo "$as_me: WARNING: pkg-config not found!" >&2;} + pkg_config="false" +fi + + +# Utility function for running pkg-config-based tests... +# +pkgs='' +pkg_check_version() { + if test "$ok" = yes ; then + req="$1" + min="$2" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $req" >&5 +$as_echo_n "checking for $req... " >&6; } + if $pkg_config --exists "$req" ; then + vers=`$pkg_config --modversion "$req"` + if $pkg_config --exists "$req >= $min" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vers" >&5 +$as_echo "$vers" >&6; } + pkgs="$pkgs $req" + return 1 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vers (wanted >= $min)" >&5 +$as_echo "$vers (wanted >= $min)" >&6; } + ok=no + return 0 + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ok=no + return 0 + fi + fi +} + + +jurassic_gtk=no +gtk_halfassed=no + +if test "$with_gtk" = yes; then + have_gtk=no + + ok="yes" + pkg_check_version gtk+-2.0 2.0.1 ; ac_gtk_version_string="$vers" + pkg_check_version gmodule-2.0 2.0.0 + pkg_check_version libxml-2.0 2.4.6 + pkg_check_version libglade-2.0 1.99.0 + pkg_check_version gdk-pixbuf-2.0 2.0.0 + pkg_check_version gdk-pixbuf-xlib-2.0 2.0.0 + have_gtk="$ok" + + if test "$have_gtk" = no; then + if test -n "$ac_gtk_version_string" ; then + gtk_halfassed="$ac_gtk_version_string" + gtk_halfassed_lib="$req" + fi + fi + + if test "$have_gtk" = yes; then + parse_gtk_version_string + jurassic_gtk=no + fi + + if test "$have_gtk" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Gtk includes" >&5 +$as_echo_n "checking for Gtk includes... " >&6; } +if ${ac_cv_gtk_config_cflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_gtk_config_cflags=`$pkg_config --cflags $pkgs` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gtk_config_cflags" >&5 +$as_echo "$ac_cv_gtk_config_cflags" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Gtk libs" >&5 +$as_echo_n "checking for Gtk libs... " >&6; } +if ${ac_cv_gtk_config_libs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_gtk_config_libs=`$pkg_config --libs $pkgs` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gtk_config_libs" >&5 +$as_echo "$ac_cv_gtk_config_libs" >&6; } + fi + + ac_gtk_config_cflags=$ac_cv_gtk_config_cflags + ac_gtk_config_libs=$ac_cv_gtk_config_libs + + GTK_EXTRA_OBJS="" + GTK_DATADIR="" + if test "$have_gtk" = yes; then + GTK_DATADIR=`$pkg_config --variable=prefix gtk+-2.0` + GTK_DATADIR="$GTK_DATADIR/share" + fi + + if test "$have_gtk" = yes; then + INCLUDES="$INCLUDES $ac_gtk_config_cflags" + GTK_LIBS="$GTK_LIBS $ac_gtk_config_libs" + $as_echo "#define HAVE_GTK 1" >>confdefs.h + + $as_echo "#define HAVE_GTK2 1" >>confdefs.h + + $as_echo "#define HAVE_XML 1" >>confdefs.h + + fi + +fi + + +# Check for the various Gnome help and URL loading programs. +# +WITH_BROWSER=gnome-open +if test "$have_gtk" = yes; then + for ac_prog in gnome-open +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_gnome_open_program+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$gnome_open_program"; then + ac_cv_prog_gnome_open_program="$gnome_open_program" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_gnome_open_program="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +gnome_open_program=$ac_cv_prog_gnome_open_program +if test -n "$gnome_open_program"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnome_open_program" >&5 +$as_echo "$gnome_open_program" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$gnome_open_program" && break +done + + for ac_prog in gnome-url-show +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_gnome_url_show_program+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$gnome_url_show_program"; then + ac_cv_prog_gnome_url_show_program="$gnome_url_show_program" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_gnome_url_show_program="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +gnome_url_show_program=$ac_cv_prog_gnome_url_show_program +if test -n "$gnome_url_show_program"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnome_url_show_program" >&5 +$as_echo "$gnome_url_show_program" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$gnome_url_show_program" && break +done + +fi + + +############################################################################### +# +# Check for -lXm. +# +############################################################################### + +have_motif=no +with_motif_req=unspecified + +# Check whether --with-motif was given. +if test "${with_motif+set}" = set; then : + withval=$with_motif; with_motif="$withval"; with_motif_req="$withval" +else + with_motif=no +fi + + + + case "$with_motif" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Motif headers" >&5 +$as_echo_n "checking for Motif headers... " >&6; } + d=$with_motif/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Motif libs" >&5 +$as_echo_n "checking for Motif libs... " >&6; } + d=$with_motif/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_motif_req="yes" + with_motif=$with_motif_req + ;; + + *) + echo "" + echo "error: argument to --with-motif must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_motif" != yes -a "$with_motif" != no ; then + echo "error: must be yes or no: --with-motif=$with_motif" + exit 1 +fi + +if test "$with_motif" = yes; then + have_motif=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "Xm/Xm.h" "ac_cv_header_Xm_Xm_h" "#include + #include + #include +" +if test "x$ac_cv_header_Xm_Xm_h" = xyes; then : + have_motif=yes + $as_echo "#define HAVE_MOTIF 1" >>confdefs.h + + MOTIF_LIBS="$MOTIF_LIBS -lXm" +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + + +if test "$have_motif" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "Xm/ComboBox.h" "ac_cv_header_Xm_ComboBox_h" "#include + #include + #include +" +if test "x$ac_cv_header_Xm_ComboBox_h" = xyes; then : + $as_echo "#define HAVE_XMCOMBOBOX 1" >>confdefs.h + +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + + +############################################################################### +# +# Checking whether Motif is really Lesstif. +# +############################################################################### + +have_lesstif=no +if test "$have_motif" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Motif is really LessTif" >&5 +$as_echo_n "checking whether Motif is really LessTif... " >&6; } +if ${ac_cv_have_lesstif+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +long vers = LesstifVersion; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_lesstif=yes +else + ac_cv_have_lesstif=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_lesstif" >&5 +$as_echo "$ac_cv_have_lesstif" >&6; } + have_lesstif=$ac_cv_have_lesstif +fi + + +lesstif_version=unknown +lesstif_version_string=unknown + +if test "$have_lesstif" = yes ; then + ltv=unknown + echo unknown > conftest-lt + { $as_echo "$as_me:${as_lineno-$LINENO}: checking LessTif version number" >&5 +$as_echo_n "checking LessTif version number... " >&6; } +if ${ac_cv_lesstif_version_string+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + if test "$cross_compiling" = yes; then : + ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + int main() { + FILE *f = fopen("conftest-lt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", LesstifVersion, + LESSTIF_VERSION, LESSTIF_REVISION); + fclose(f); + exit(0); + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ltv=`cat conftest-lt` + ac_cv_lesstif_version=`echo $ltv | sed 's/ .*//'` + ac_cv_lesstif_version_string=`echo $ltv | sed 's/.* //'` +else + ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lesstif_version_string" >&5 +$as_echo "$ac_cv_lesstif_version_string" >&6; } + rm -rf conftest-lt + lesstif_version=$ac_cv_lesstif_version + lesstif_version_string=$ac_cv_lesstif_version_string + +fi + + +if test "$have_motif" = yes ; then + mtv=unknown + echo unknown > conftest-mt + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Motif version number" >&5 +$as_echo_n "checking Motif version number... " >&6; } +if ${ac_cv_motif_version_string+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + if test "$cross_compiling" = yes; then : + ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + int main() { + FILE *f = fopen("conftest-mt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", XmVersion, + XmVERSION, XmREVISION); + fclose(f); + exit(0); + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + mtv=`cat conftest-mt` + ac_cv_motif_version=`echo $mtv | sed 's/ .*//'` + ac_cv_motif_version_string=`echo $mtv | sed 's/.* //'` +else + ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + CPPFLAGS="$ac_save_CPPFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_motif_version_string" >&5 +$as_echo "$ac_cv_motif_version_string" >&6; } + rm -rf conftest-mt + motif_version=$ac_cv_motif_version + motif_version_string=$ac_cv_motif_version_string + +fi + + +############################################################################### +# +# Checking whether Motif requires -lXpm. +# +# If this is Motif 2.x, and we have XPM, then link against XPM as well. +# The deal is, Motif 2.x requires XPM -- but it's a compilation option +# of the library whether to build the XPM code into libXm, or whether +# to rely on an external libXm. So the only way to tell whether XPM is +# a link-time requirement is to examine libXm.a, which is very +# difficult to do in an autoconf script. So... if it's Motif 2.x, we +# always link against XPM if the XPM lib exists (and this will be a +# no-op if libXm happens to already have the XPM code in it.) +# +############################################################################### + +motif_requires_xpm=no +if test "$have_motif" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Motif requires XPM" >&5 +$as_echo_n "checking whether Motif requires XPM... " >&6; } + if test "$motif_version" = "unknown" || test "$motif_version" -ge 2000 + then + motif_requires_xpm=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: maybe" >&5 +$as_echo "maybe" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi +fi + + +############################################################################### +# +# Checking whether Motif requires -lXp. +# +# Some versions of Motif (2.1.0, at least) require -lXp, the "X Printing +# Extension". Why this extension isn't in -lXext with all the others, +# I have no idea. +# +############################################################################### + +have_xp_ext=no +if test "$have_motif" = yes ; then + have_xp_ext=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XpQueryExtension in -lXp" >&5 +$as_echo_n "checking for XpQueryExtension in -lXp... " >&6; } +if ${ac_cv_lib_Xp_XpQueryExtension+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXp -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XpQueryExtension (); +int +main () +{ +return XpQueryExtension (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xp_XpQueryExtension=yes +else + ac_cv_lib_Xp_XpQueryExtension=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xp_XpQueryExtension" >&5 +$as_echo "$ac_cv_lib_Xp_XpQueryExtension" >&6; } +if test "x$ac_cv_lib_Xp_XpQueryExtension" = xyes; then : + have_xp_ext=yes; MOTIF_LIBS="$MOTIF_LIBS -lXp" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + +fi + + +############################################################################### +# +# Checking whether Motif requires -lXintl (for _Xsetlocale.) +# +############################################################################### + +have_xintl=no +if test "$have_motif" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _Xsetlocale in -lXintl" >&5 +$as_echo_n "checking for _Xsetlocale in -lXintl... " >&6; } +if ${ac_cv_lib_Xintl__Xsetlocale+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXintl -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _Xsetlocale (); +int +main () +{ +return _Xsetlocale (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xintl__Xsetlocale=yes +else + ac_cv_lib_Xintl__Xsetlocale=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xintl__Xsetlocale" >&5 +$as_echo "$ac_cv_lib_Xintl__Xsetlocale" >&6; } +if test "x$ac_cv_lib_Xintl__Xsetlocale" = xyes; then : + have_xintl=yes +else + have_xintl=no +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + if test "$have_xintl" = yes; then + MOTIF_LIBS="$MOTIF_LIBS -lXintl" + fi +fi + + +############################################################################### +# +# Check for -lGL or -lMesaGL. +# +############################################################################### + +have_gl=no +ac_have_mesa_gl=no +with_gl_req=unspecified +gl_halfassed=no + +# Check whether --with-gl was given. +if test "${with_gl+set}" = set; then : + withval=$with_gl; with_gl="$withval"; with_gl_req="$withval" +else + with_gl=yes +fi + + + + case "$with_gl" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GL headers" >&5 +$as_echo_n "checking for GL headers... " >&6; } + d=$with_gl/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GL libs" >&5 +$as_echo_n "checking for GL libs... " >&6; } + d=$with_gl/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_gl_req="yes" + with_gl=$with_gl_req + ;; + + *) + echo "" + echo "error: argument to --with-gl must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +ac_mesagl_version=unknown +ac_mesagl_version_string=unknown + +if test "$with_gl" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "GL/gl.h" "ac_cv_header_GL_gl_h" "$ac_includes_default" +if test "x$ac_cv_header_GL_gl_h" = xyes; then : + have_gl=yes +else + have_gl=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_gl" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "GL/glx.h" "ac_cv_header_GL_glx_h" "#include +" +if test "x$ac_cv_header_GL_glx_h" = xyes; then : + have_gl=yes +else + have_gl=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + # If we have the headers, try and figure out which vendor it's from. + # + if test "$have_gl" = yes ; then + + # We need to know whether it's MesaGL so that we know which libraries + # to link against. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GL is really MesaGL" >&5 +$as_echo_n "checking whether GL is really MesaGL... " >&6; } +if ${ac_cv_have_mesa_gl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_have_mesa_gl=no + if test "$ac_macosx" = no; then + # WTF! MacOS 10.5.0 ships the Mesa GL headers! + # It's not really Mesa, is it? + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Mesa|MESA" >/dev/null 2>&1; then : + ac_cv_have_mesa_gl=yes +fi +rm -rf conftest* + + CPPFLAGS="$ac_save_CPPFLAGS" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_mesa_gl" >&5 +$as_echo "$ac_cv_have_mesa_gl" >&6; } + ac_have_mesa_gl=$ac_cv_have_mesa_gl + + gl_lib_1="" + GL_LIBS="" + + if test "$ac_macosx" = yes; then + + # Without these, every link against libGL gets a bunch of useless + # warnings. + # + osx_crud="-bind_at_load -multiply_defined suppress" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding \"$osx_crud\" to GL_LIBS" >&5 +$as_echo "adding \"$osx_crud\" to GL_LIBS" >&6; } + GL_LIBS="$GL_LIBS $osx_crud" + unset osx_crud + + # New lossage in 10.5.0: without this, we get: + # ld: cycle in dylib re-exports with /usr/X11/lib/libGL.dylib + # + osx_crud="/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib" + osx_crud="-Wl,-dylib_file,${osx_crud}:${osx_crud}" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding \"$osx_crud\" to GL_LIBS" >&5 +$as_echo "adding \"$osx_crud\" to GL_LIBS" >&6; } + GL_LIBS="$GL_LIBS $osx_crud" + unset osx_crud + + # New lossage in 10.6.8: we can't allow -L/opt/local/lib to be in the + # link line, or at runtime XQueryExtension gets a segv due to some kind + # of library version skew. Libs must come from /usr/X11/lib even if + # $prefix and/or $exec_prefix are set to /opt/local/. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: omitting \"$libdir\" from LDFLAGS" >&5 +$as_echo "omitting \"$libdir\" from LDFLAGS" >&6; } + libdir='' + + fi + + + # Some versions of MesaGL are compiled to require -lpthread. + # So if the Mesa headers exist, and -lpthread exists, then always + # link -lpthread after the Mesa libs (be they named -lGL or -lMesaGL.) + # + if test "$ac_have_mesa_gl" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +$as_echo_n "checking for pthread_create in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_create=yes +else + ac_cv_lib_pthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : + GL_LIBS="-lpthread" +fi + + fi + + + # If we have Mesa headers, check to see if we can link against -lMesaGL. + # If we don't have Mesa headers, or we don't have -lMesaGL, try -lGL. + # Else, warn that GL is busted. (We have the headers, but no libs.) + # + + if test "$ac_have_mesa_gl" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glXCreateContext in -lMesaGL" >&5 +$as_echo_n "checking for glXCreateContext in -lMesaGL... " >&6; } +if ${ac_cv_lib_MesaGL_glXCreateContext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lMesaGL -lMesaGLU $GL_LIBS -lX11 -lXext $VIDMODE_LIBS -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glXCreateContext (); +int +main () +{ +return glXCreateContext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_MesaGL_glXCreateContext=yes +else + ac_cv_lib_MesaGL_glXCreateContext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_MesaGL_glXCreateContext" >&5 +$as_echo "$ac_cv_lib_MesaGL_glXCreateContext" >&6; } +if test "x$ac_cv_lib_MesaGL_glXCreateContext" = xyes; then : + gl_lib_1="MesaGL" + GL_LIBS="-lMesaGL -lMesaGLU $VIDMODE_LIBS $GL_LIBS" +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + if test "$gl_lib_1" = "" ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glXCreateContext in -lGL" >&5 +$as_echo_n "checking for glXCreateContext in -lGL... " >&6; } +if ${ac_cv_lib_GL_glXCreateContext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL -lGLU $GL_LIBS -lX11 -lXext $VIDMODE_LIBS -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glXCreateContext (); +int +main () +{ +return glXCreateContext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_glXCreateContext=yes +else + ac_cv_lib_GL_glXCreateContext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glXCreateContext" >&5 +$as_echo "$ac_cv_lib_GL_glXCreateContext" >&6; } +if test "x$ac_cv_lib_GL_glXCreateContext" = xyes; then : + gl_lib_1="GL" + GL_LIBS="-lGL -lGLU $VIDMODE_LIBS $GL_LIBS" +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + + if test "$gl_lib_1" = "" ; then + # we have headers, but no libs -- bail. + have_gl=no + ac_have_mesa_gl=no + gl_halfassed=yes + else + # linking works -- we can build the GL hacks. + $as_echo "#define HAVE_GL 1" >>confdefs.h + + if test "$ac_have_mesa_gl" = yes ; then + $as_echo "#define HAVE_MESA_GL 1" >>confdefs.h + + fi + fi + fi + + + # Now that we know we have GL headers and libs, do some more GL testing. + # + + if test "$have_gl" = yes ; then + # If it's MesaGL, we'd like to issue a warning if the version number + # is less than or equal to 2.6, because that version had a security bug. + # + if test "$ac_have_mesa_gl" = yes; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking MesaGL version number" >&5 +$as_echo_n "checking MesaGL version number... " >&6; } +if ${ac_cv_mesagl_version_string+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.$ac_ext < +#ifndef MESA_MAJOR_VERSION +# include +# ifdef XMESA_MAJOR_VERSION + /* Around Mesa 3.2, they took out the Mesa version number, so instead, + we have to check the XMesa version number (the number of the X protocol + support, which seems to be the same as the Mesa version number.) + */ +# define MESA_MAJOR_VERSION XMESA_MAJOR_VERSION +# define MESA_MINOR_VERSION XMESA_MINOR_VERSION +# else + /* Oh great. Some time after 3.4, they took out the xmesa.h header file, + so we have no way of telling what version of Mesa this is at all. + So, we'll guess that the osmesa version (the "offscreen protocol") + is less than or equal to the real mesa version number. Except that + if OSmesa is 3.3, assume at least Mesa 3.4, since OSmesa was 3.3 in + Mesa 3.4. And Mesa 3.3 had xmesa.h. What a complete load of shit! + */ +# include +# define MESA_MAJOR_VERSION OSMESA_MAJOR_VERSION +# define MESA_MINOR_VERSION OSMESA_MINOR_VERSION or newer, probably? +# if OSMESA_MAJOR_VERSION == 3 && OSMESA_MINOR_VERSION == 3 +# undef MESA_MINOR_VERSION +# define MESA_MINOR_VERSION 4 or newer, probably? +# endif +# endif +#endif +configure: MESA_MAJOR_VERSION MESA_MINOR_VERSION +EOF + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + mglv=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | grep configure:` + + # M4 sucks!! + + mglv=`echo "$mglv" | sed -n \ + 's/^configure: *\([0-9][0-9]*\) *\([0-9].*\)$/\1.\2/p'` + + + rm -rf conftest.$ac_ext + + CPPFLAGS="$ac_save_CPPFLAGS" + + if test "$mglv" = ""; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + else + ac_mesagl_version_string="$mglv" + # M4 sucks!! + + maj=`echo "$mglv" | sed -n 's/^\([0-9][0-9]*\)\..*$/\1/p'` + min=`echo "$mglv" | sed -n 's/^.*\.\([0-9][0-9]*\).*$/\1/p'` + + ac_mesagl_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_mesagl_version"; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + fi + fi + ac_cv_mesagl_version=$ac_mesagl_version + ac_cv_mesagl_version_string=$ac_mesagl_version_string + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mesagl_version_string" >&5 +$as_echo "$ac_cv_mesagl_version_string" >&6; } + ac_mesagl_version=$ac_cv_mesagl_version + ac_mesagl_version_string=$ac_cv_mesagl_version_string + fi + + + # Check for OpenGL 1.1 features. + # + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + as_ac_Lib=`$as_echo "ac_cv_lib_$gl_lib_1''_glBindTexture" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glBindTexture in -l$gl_lib_1" >&5 +$as_echo_n "checking for glBindTexture in -l$gl_lib_1... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$gl_lib_1 $GL_LIBS -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glBindTexture (); +int +main () +{ +return glBindTexture (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + $as_echo "#define HAVE_GLBINDTEXTURE 1" >>confdefs.h + +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + +elif test "$with_gl" != no; then + echo "error: must be yes or no: --with-gl=$with_gl" + exit 1 +fi + + +############################################################################### +# +# Check for -lgle. +# +############################################################################### + +have_gle=no +with_gle_req=unspecified +gle_halfassed=no + +# Check whether --with-gle was given. +if test "${with_gle+set}" = set; then : + withval=$with_gle; with_gle="$withval"; with_gle_req="$withval" +else + with_gle=yes +fi + + + + case "$with_gle" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLE headers" >&5 +$as_echo_n "checking for GLE headers... " >&6; } + d=$with_gle/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLE libs" >&5 +$as_echo_n "checking for GLE libs... " >&6; } + d=$with_gle/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_gle_req="yes" + with_gle=$with_gle_req + ;; + + *) + echo "" + echo "error: argument to --with-gle must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +GLE_LIBS="" + +if test "$have_gl" = no ; then + true +elif test "$with_gle" = yes; then + + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "GL/gle.h" "ac_cv_header_GL_gle_h" "#include +" +if test "x$ac_cv_header_GL_gle_h" = xyes; then : + have_gle3=yes +else + have_gle3=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_gle3" = yes ; then + have_gle=yes; + else + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "GL/gutil.h" "ac_cv_header_GL_gutil_h" "#include +" +if test "x$ac_cv_header_GL_gutil_h" = xyes; then : + have_gle=yes +else + have_gle=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_gle" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "GL/tube.h" "ac_cv_header_GL_tube_h" "#include +" +if test "x$ac_cv_header_GL_tube_h" = xyes; then : + have_gle=yes +else + have_gle=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + fi + + if test "$have_gle" = yes ; then + have_gle=no + gle_halfassed=yes + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gleCreateGC in -lgle" >&5 +$as_echo_n "checking for gleCreateGC in -lgle... " >&6; } +if ${ac_cv_lib_gle_gleCreateGC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gleCreateGC (); +int +main () +{ +return gleCreateGC (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gle_gleCreateGC=yes +else + ac_cv_lib_gle_gleCreateGC=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gle_gleCreateGC" >&5 +$as_echo "$ac_cv_lib_gle_gleCreateGC" >&6; } +if test "x$ac_cv_lib_gle_gleCreateGC" = xyes; then : + have_gle=yes; gle_halfassed=no; GLE_LIBS="-lgle" +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + if test "$have_gle" = yes ; then + have_gle=no + gle_halfassed=yes + + # sometimes the libmatrix stuff is included in libgle. look there first. +# +# I don't get it. For some reason, this test passes on SGI, as if +# uview_direction_d() was in libgle -- but it's not, it's in libmatrix. +# Yet the link is succeeding. Why??? +# +# AC_CHECK_X_LIB(gle, uview_direction_d, +# [have_gle=yes; gle_halfassed=no], +# [], $GL_LIBS -lX11 -lXext -lm) + + # As of GLE 3 this is in libgle, and has changed name to uview_direction! + # *sigh* + if test "$have_gle3" = yes ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uview_direction in -lgle" >&5 +$as_echo_n "checking for uview_direction in -lgle... " >&6; } +if ${ac_cv_lib_gle_uview_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgle $GL_LIBS -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char uview_direction (); +int +main () +{ +return uview_direction (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gle_uview_direction=yes +else + ac_cv_lib_gle_uview_direction=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gle_uview_direction" >&5 +$as_echo "$ac_cv_lib_gle_uview_direction" >&6; } +if test "x$ac_cv_lib_gle_uview_direction" = xyes; then : + have_gle=yes; gle_halfassed=no +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + # if it wasn't in libgle, then look in libmatrix. + if test "$have_gle" = no ; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uview_direction_d in -lmatrix" >&5 +$as_echo_n "checking for uview_direction_d in -lmatrix... " >&6; } +if ${ac_cv_lib_matrix_uview_direction_d+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmatrix $GL_LIBS -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char uview_direction_d (); +int +main () +{ +return uview_direction_d (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_matrix_uview_direction_d=yes +else + ac_cv_lib_matrix_uview_direction_d=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_matrix_uview_direction_d" >&5 +$as_echo "$ac_cv_lib_matrix_uview_direction_d" >&6; } +if test "x$ac_cv_lib_matrix_uview_direction_d" = xyes; then : + have_gle=yes; gle_halfassed=no; + GLE_LIBS="$GLE_LIBS -lmatrix" +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + fi + + if test "$have_gle" = yes ; then + $as_echo "#define HAVE_GLE 1" >>confdefs.h + + if test "$have_gle3" = yes ; then + $as_echo "#define HAVE_GLE3 1" >>confdefs.h + + fi + fi + +elif test "$with_gle" != no; then + echo "error: must be yes or no: --with-gle=$with_gle" + exit 1 + +fi + + +############################################################################### +# +# Handle --with-gles +# +############################################################################### + +with_gles_req=unspecified + +# Check whether --with-gles was given. +if test "${with_gles+set}" = set; then : + withval=$with_gles; with_gles="$withval"; with_gles_req="$withval" +else + with_gles=no +fi + + + + case "$with_gles" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JWZGLES headers" >&5 +$as_echo_n "checking for JWZGLES headers... " >&6; } + d=$with_gles/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JWZGLES libs" >&5 +$as_echo_n "checking for JWZGLES libs... " >&6; } + d=$with_gles/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_gles_req="yes" + with_gles=$with_gles_req + ;; + + *) + echo "" + echo "error: argument to --with-gles must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_gles" = yes; then + have_gles=yes + $as_echo "#define HAVE_JWZGLES 1" >>confdefs.h + + JWZGLES_OBJS="jwzgles.o" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using OpenGL ES compatiblity shim" >&5 +$as_echo "using OpenGL ES compatiblity shim" >&6; } +elif test "$with_gles" != no; then + echo "error: must be yes or no: --with-gles=$with_xpm" + exit 1 +fi + +# May want to phase out glBitmap even in a non-GLES world. +# +if test "$have_gles" = yes; then + GLFPS_OBJS="fps-gl.o glxfonts.o texfont.o" + GLFONT_OBJS="" +else + $as_echo "#define HAVE_GLBITMAP 1" >>confdefs.h + + GLFPS_OBJS="fps-gl.o glxfonts.o" + GLFONT_OBJS="texfont.o" +fi + + +############################################################################### +# +# Check for -lgdk_pixbuf. +# These tests are for gdk_pixbuf usage of the hacks, +# not xscreensaver-demo (thus we have to test again to get +# the libraries right: don't want to pull in all of GTK +# for the hacks.) +# +############################################################################### + +have_gdk_pixbuf=no +with_gdk_pixbuf_req=unspecified + +# Check whether --with-pixbuf was given. +if test "${with_pixbuf+set}" = set; then : + withval=$with_pixbuf; with_gdk_pixbuf="$withval"; with_gdk_pixbuf_req="$withval" +else + with_gdk_pixbuf=yes +fi + + +# if --with-pixbuf=/directory/ was specified, remember that directory so that +# we can also look for the `gdk-pixbuf-config' program in that directory. +case "$with_gdk_pixbuf" in + /*) + gdk_pixbuf_dir="$with_gdk_pixbuf" + ;; + *) + gdk_pixbuf_dir="" + ;; +esac + + + case "$with_gdk_pixbuf" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GDK_PIXBUF headers" >&5 +$as_echo_n "checking for GDK_PIXBUF headers... " >&6; } + d=$with_gdk_pixbuf/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GDK_PIXBUF libs" >&5 +$as_echo_n "checking for GDK_PIXBUF libs... " >&6; } + d=$with_gdk_pixbuf/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_gdk_pixbuf_req="yes" + with_gdk_pixbuf=$with_gdk_pixbuf_req + ;; + + *) + echo "" + echo "error: argument to --with-pixbuf must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_gdk_pixbuf" != yes -a "$with_gdk_pixbuf" != no ; then + echo "error: must be yes or no: --with-pixbuf=$with_gdk_pixbuf" + exit 1 +fi + +if test "$with_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + + pkgs='' + ok="yes" + + pkg_check_version gdk-pixbuf-2.0 2.0.0 + pkg_check_version gdk-pixbuf-xlib-2.0 2.0.0 + have_gdk_pixbuf="$ok" + + if test "$have_gdk_pixbuf" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdk-pixbuf includes" >&5 +$as_echo_n "checking for gdk-pixbuf includes... " >&6; } +if ${ac_cv_gdk_pixbuf_config_cflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_gdk_pixbuf_config_cflags=`$pkg_config --cflags $pkgs` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gdk_pixbuf_config_cflags" >&5 +$as_echo "$ac_cv_gdk_pixbuf_config_cflags" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdk-pixbuf libs" >&5 +$as_echo_n "checking for gdk-pixbuf libs... " >&6; } +if ${ac_cv_gdk_pixbuf_config_libs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_gdk_pixbuf_config_libs=`$pkg_config --libs $pkgs` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gdk_pixbuf_config_libs" >&5 +$as_echo "$ac_cv_gdk_pixbuf_config_libs" >&6; } + fi + + ac_gdk_pixbuf_config_cflags=$ac_cv_gdk_pixbuf_config_cflags + ac_gdk_pixbuf_config_libs=$ac_cv_gdk_pixbuf_config_libs + + + if test "$have_gdk_pixbuf" = yes; then + # + # we appear to have pixbuf; check for headers/libs to be sure. + # + ac_save_gdk_pixbuf_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ac_gdk_pixbuf_config_cflags" + + have_gdk_pixbuf=no + + # check for header A... + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "gdk-pixbuf/gdk-pixbuf.h" "ac_cv_header_gdk_pixbuf_gdk_pixbuf_h" "$ac_includes_default" +if test "x$ac_cv_header_gdk_pixbuf_gdk_pixbuf_h" = xyes; then : + have_gdk_pixbuf=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that worked, check for header B... + if test "$have_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + gdk_pixbuf_halfassed=yes + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "gdk-pixbuf/gdk-pixbuf-xlib.h" "ac_cv_header_gdk_pixbuf_gdk_pixbuf_xlib_h" "$ac_includes_default" +if test "x$ac_cv_header_gdk_pixbuf_gdk_pixbuf_xlib_h" = xyes; then : + have_gdk_pixbuf=yes + gdk_pixbuf_halfassed=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # yay, it has a new name in Gtk 2.x... + if test "$have_gdk_pixbuf" = no; then + have_gdk_pixbuf=no + gdk_pixbuf_halfassed=yes + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "gdk-pixbuf-xlib/gdk-pixbuf-xlib.h" "ac_cv_header_gdk_pixbuf_xlib_gdk_pixbuf_xlib_h" "$ac_includes_default" +if test "x$ac_cv_header_gdk_pixbuf_xlib_gdk_pixbuf_xlib_h" = xyes; then : + have_gdk_pixbuf=yes + gdk_pixbuf_halfassed=no +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + fi + CPPFLAGS="$ac_save_gdk_pixbuf_CPPFLAGS" + fi + + if test "$have_gdk_pixbuf" = yes; then + # we have the headers, now check for the libraries + have_gdk_pixbuf=no + gdk_pixbuf_halfassed=yes + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for gdk_pixbuf usability..." >&5 +$as_echo "checking for gdk_pixbuf usability..." >&6; } + + # library A... + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdk_pixbuf_new_from_file in -lc" >&5 +$as_echo_n "checking for gdk_pixbuf_new_from_file in -lc... " >&6; } +if ${ac_cv_lib_c_gdk_pixbuf_new_from_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $ac_gdk_pixbuf_config_libs -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gdk_pixbuf_new_from_file (); +int +main () +{ +return gdk_pixbuf_new_from_file (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_gdk_pixbuf_new_from_file=yes +else + ac_cv_lib_c_gdk_pixbuf_new_from_file=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_gdk_pixbuf_new_from_file" >&5 +$as_echo "$ac_cv_lib_c_gdk_pixbuf_new_from_file" >&6; } +if test "x$ac_cv_lib_c_gdk_pixbuf_new_from_file" = xyes; then : + have_gdk_pixbuf=yes +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + # library B... + if test "$have_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdk_pixbuf_xlib_init in -lc" >&5 +$as_echo_n "checking for gdk_pixbuf_xlib_init in -lc... " >&6; } +if ${ac_cv_lib_c_gdk_pixbuf_xlib_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $ac_gdk_pixbuf_config_libs -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gdk_pixbuf_xlib_init (); +int +main () +{ +return gdk_pixbuf_xlib_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_gdk_pixbuf_xlib_init=yes +else + ac_cv_lib_c_gdk_pixbuf_xlib_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_gdk_pixbuf_xlib_init" >&5 +$as_echo "$ac_cv_lib_c_gdk_pixbuf_xlib_init" >&6; } +if test "x$ac_cv_lib_c_gdk_pixbuf_xlib_init" = xyes; then : + have_gdk_pixbuf=yes + gdk_pixbuf_halfassed=no +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + fi + + if test "$have_gdk_pixbuf" = yes; then + INCLUDES="$INCLUDES $ac_gdk_pixbuf_config_cflags" + XPM_LIBS="$ac_gdk_pixbuf_config_libs" + $as_echo "#define HAVE_GDK_PIXBUF 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for gdk_pixbuf usability... no" >&5 +$as_echo "checking for gdk_pixbuf usability... no" >&6; } + fi + + if test "$have_gdk_pixbuf" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdk_pixbuf_apply_embedded_orientation in -lc" >&5 +$as_echo_n "checking for gdk_pixbuf_apply_embedded_orientation in -lc... " >&6; } +if ${ac_cv_lib_c_gdk_pixbuf_apply_embedded_orientation+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $ac_gdk_pixbuf_config_libs -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gdk_pixbuf_apply_embedded_orientation (); +int +main () +{ +return gdk_pixbuf_apply_embedded_orientation (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_gdk_pixbuf_apply_embedded_orientation=yes +else + ac_cv_lib_c_gdk_pixbuf_apply_embedded_orientation=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_gdk_pixbuf_apply_embedded_orientation" >&5 +$as_echo "$ac_cv_lib_c_gdk_pixbuf_apply_embedded_orientation" >&6; } +if test "x$ac_cv_lib_c_gdk_pixbuf_apply_embedded_orientation" = xyes; then : + $as_echo "#define HAVE_GDK_PIXBUF_APPLY_EMBEDDED_ORIENTATION 1" >>confdefs.h + +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi +fi + + +############################################################################### +# +# Check for -lXpm. +# +############################################################################### + +have_xpm=no +with_xpm_req=unspecified + +# Check whether --with-xpm was given. +if test "${with_xpm+set}" = set; then : + withval=$with_xpm; with_xpm="$withval"; with_xpm_req="$withval" +else + with_xpm=yes +fi + + + + case "$with_xpm" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XPM headers" >&5 +$as_echo_n "checking for XPM headers... " >&6; } + d=$with_xpm/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XPM libs" >&5 +$as_echo_n "checking for XPM libs... " >&6; } + d=$with_xpm/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xpm_req="yes" + with_xpm=$with_xpm_req + ;; + + *) + echo "" + echo "error: argument to --with-xpm must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xpm" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/xpm.h" "ac_cv_header_X11_xpm_h" "#include +" +if test "x$ac_cv_header_X11_xpm_h" = xyes; then : + have_xpm=yes + $as_echo "#define HAVE_XPM 1" >>confdefs.h + + XPM_LIBS="-lXpm $XPM_LIBS" +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" +elif test "$with_xpm" != no; then + echo "error: must be yes or no: --with-xpm=$with_xpm" + exit 1 +fi + +# See comment near $motif_requires_xpm, above. +# Need to do this here, after both Motif and XPM have been checked for. +# +if test "$have_motif" = yes -a "$have_xpm" = yes ; then + if test "$motif_requires_xpm" = yes ; then + MOTIF_LIBS="$MOTIF_LIBS $XPM_LIBS" + fi +fi + +if test "$XPM_LIBS" = "" ; then + XPM_LIBS=$(MINIXPM) +fi + + +############################################################################### +# +# Check for -ljpeg +# +############################################################################### + +have_jpeg=no +with_jpeg_req=unspecified +jpeg_halfassed=no + +# Check whether --with-jpeg was given. +if test "${with_jpeg+set}" = set; then : + withval=$with_jpeg; with_jpeg="$withval"; with_jpeg_req="$withval" +else + with_jpeg=yes +fi + + + + case "$with_jpeg" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG headers" >&5 +$as_echo_n "checking for JPEG headers... " >&6; } + d=$with_jpeg/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG libs" >&5 +$as_echo_n "checking for JPEG libs... " >&6; } + d=$with_jpeg/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_jpeg_req="yes" + with_jpeg=$with_jpeg_req + ;; + + *) + echo "" + echo "error: argument to --with-jpeg must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_jpeg" != yes -a "$with_jpeg" != no ; then + echo "error: must be yes or no: --with-jpeg=$with_jpeg" + exit 1 +fi + +if test "$with_jpeg" = yes; then + + have_jpeg=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" +if test "x$ac_cv_header_jpeglib_h" = xyes; then : + have_jpeg=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + if test "$have_jpeg" = yes; then + # we have the header, now check for the library + have_jpeg=no + jpeg_halfassed=yes + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_start_compress in -ljpeg" >&5 +$as_echo_n "checking for jpeg_start_compress in -ljpeg... " >&6; } +if ${ac_cv_lib_jpeg_jpeg_start_compress+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ljpeg $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char jpeg_start_compress (); +int +main () +{ +return jpeg_start_compress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_jpeg_jpeg_start_compress=yes +else + ac_cv_lib_jpeg_jpeg_start_compress=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_start_compress" >&5 +$as_echo "$ac_cv_lib_jpeg_jpeg_start_compress" >&6; } +if test "x$ac_cv_lib_jpeg_jpeg_start_compress" = xyes; then : + have_jpeg=yes + jpeg_halfassed=no + JPEG_LIBS="-ljpeg" + $as_echo "#define HAVE_JPEGLIB 1" >>confdefs.h + +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi +fi + + +############################################################################### +# +# Check for pty support: this allows 'phosphor' and 'apple2' +# to run curses-based programs, or be used as terminal windows. +# +############################################################################### + +PTY_LIBS= +for ac_header in pty.h util.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lutil" >&5 +$as_echo_n "checking for forkpty in -lutil... " >&6; } +if ${ac_cv_lib_util_forkpty+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char forkpty (); +int +main () +{ +return forkpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_util_forkpty=yes +else + ac_cv_lib_util_forkpty=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_forkpty" >&5 +$as_echo "$ac_cv_lib_util_forkpty" >&6; } +if test "x$ac_cv_lib_util_forkpty" = xyes; then : + PTY_LIBS="-lutil" + ac_have_forkpty=yes + $as_echo "#define HAVE_FORKPTY 1" >>confdefs.h + +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + +if test "$ac_have_forkpty" != yes ; then + # we don't need (or have) -lutil on MacOS 10.4.2... + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lc" >&5 +$as_echo_n "checking for forkpty in -lc... " >&6; } +if ${ac_cv_lib_c_forkpty+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char forkpty (); +int +main () +{ +return forkpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_forkpty=yes +else + ac_cv_lib_c_forkpty=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_forkpty" >&5 +$as_echo "$ac_cv_lib_c_forkpty" >&6; } +if test "x$ac_cv_lib_c_forkpty" = xyes; then : + PTY_LIBS="" + $as_echo "#define HAVE_FORKPTY 1" >>confdefs.h + +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + +fi + +############################################################################### +# +# Check for the XSHM server extension. +# +############################################################################### + +have_xshm=no +with_xshm_req=unspecified + +# Check whether --with-xshm-ext was given. +if test "${with_xshm_ext+set}" = set; then : + withval=$with_xshm_ext; with_xshm="$withval"; with_xshm_req="$withval" +else + with_xshm=yes +fi + + + + case "$with_xshm" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XSHM headers" >&5 +$as_echo_n "checking for XSHM headers... " >&6; } + d=$with_xshm/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XSHM libs" >&5 +$as_echo_n "checking for XSHM libs... " >&6; } + d=$with_xshm/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xshm_req="yes" + with_xshm=$with_xshm_req + ;; + + *) + echo "" + echo "error: argument to --with-xshm-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xshm" = yes; then + + # first check for Xshm.h. + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/XShm.h" "ac_cv_header_X11_extensions_XShm_h" "#include +" +if test "x$ac_cv_header_X11_extensions_XShm_h" = xyes; then : + have_xshm=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + + # if that succeeded, then check for sys/ipc.h. + if test "$have_xshm" = yes; then + have_xshm=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "sys/ipc.h" "ac_cv_header_sys_ipc_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_ipc_h" = xyes; then : + have_xshm=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + # if that succeeded, then check for sys/shm.h. + if test "$have_xshm" = yes; then + have_xshm=no + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_mongrel "$LINENO" "sys/shm.h" "ac_cv_header_sys_shm_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_shm_h" = xyes; then : + have_xshm=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + fi + + # AIX is pathological, as usual: apparently it's normal for the Xshm headers + # to exist, but the library code to not exist. And even better, the library + # code is in its own library: libXextSam.a. So, if we're on AIX, and that + # lib doesn't exist, give up. (This lib gets added to X_EXTRA_LIBS, and + # that's not quite right, but close enough.) + # + case "$host" in + *-aix*) + if `uname -v` -eq 3 ; then + have_xshm=no + + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XShmQueryExtension in -lXextSam" >&5 +$as_echo_n "checking for XShmQueryExtension in -lXextSam... " >&6; } +if ${ac_cv_lib_XextSam_XShmQueryExtension+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXextSam -lX11 -lXext -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XShmQueryExtension (); +int +main () +{ +return XShmQueryExtension (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_XextSam_XShmQueryExtension=yes +else + ac_cv_lib_XextSam_XShmQueryExtension=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_XextSam_XShmQueryExtension" >&5 +$as_echo "$ac_cv_lib_XextSam_XShmQueryExtension" >&6; } +if test "x$ac_cv_lib_XextSam_XShmQueryExtension" = xyes; then : + have_xshm=yes; X_EXTRA_LIBS="$X_EXTRA_LIBS -lXextSam" +else + true +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + + fi + ;; + esac + + # if that succeeded, then we've really got it. + if test "$have_xshm" = yes; then + $as_echo "#define HAVE_XSHM_EXTENSION 1" >>confdefs.h + + fi + +elif test "$with_xshm" != no; then + echo "error: must be yes or no: --with-xshm-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the DOUBLE-BUFFER server extension. +# +############################################################################### + +have_xdbe=no +with_xdbe_req=unspecified + +# Check whether --with-xdbe-ext was given. +if test "${with_xdbe_ext+set}" = set; then : + withval=$with_xdbe_ext; with_xdbe="$withval"; with_xdbe_req="$withval" +else + with_xdbe=yes +fi + + + + case "$with_xdbe" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DOUBLE-BUFFER headers" >&5 +$as_echo_n "checking for DOUBLE-BUFFER headers... " >&6; } + d=$with_xdbe/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DOUBLE-BUFFER libs" >&5 +$as_echo_n "checking for DOUBLE-BUFFER libs... " >&6; } + d=$with_xdbe/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_xdbe_req="yes" + with_xdbe=$with_xdbe_req + ;; + + *) + echo "" + echo "error: argument to --with-xdbe-ext must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_xdbe" = yes; then + + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xdbe.h" "ac_cv_header_X11_extensions_Xdbe_h" "#include +" +if test "x$ac_cv_header_X11_extensions_Xdbe_h" = xyes; then : + have_xdbe=yes +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" + if test "$have_xdbe" = yes; then + $as_echo "#define HAVE_DOUBLE_BUFFER_EXTENSION 1" >>confdefs.h + + fi + +elif test "$with_xdbe" != no; then + echo "error: must be yes or no: --with-xdbe-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI XReadDisplay server extension. +# +# Note: this has to be down here, rather than up with the other server +# extension tests, so that the output of `configure --help' is in the +# right order. Arrgh! +# +############################################################################### + +have_readdisplay=no +with_readdisplay_req=unspecified + +# Check whether --with-readdisplay was given. +if test "${with_readdisplay+set}" = set; then : + withval=$with_readdisplay; with_readdisplay="$withval"; with_readdisplay_req="$withval" +else + with_readdisplay=yes +fi + + + + case "$with_readdisplay" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XReadDisplay headers" >&5 +$as_echo_n "checking for XReadDisplay headers... " >&6; } + d=$with_readdisplay/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XReadDisplay libs" >&5 +$as_echo_n "checking for XReadDisplay libs... " >&6; } + d=$with_readdisplay/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + with_readdisplay_req="yes" + with_readdisplay=$with_readdisplay_req + ;; + + *) + echo "" + echo "error: argument to --with-readdisplay must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$with_readdisplay" = yes; then + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/readdisplay.h" "ac_cv_header_X11_extensions_readdisplay_h" "#include +" +if test "x$ac_cv_header_X11_extensions_readdisplay_h" = xyes; then : + $as_echo "#define HAVE_READ_DISPLAY_EXTENSION 1" >>confdefs.h + +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" +elif test "$with_readdisplay" != no; then + echo "error: must be yes or no: --with-readdisplay=$with_readdisplay" + exit 1 +fi + + +############################################################################### +# +# Check for a directory full of images to use as the default value +# of the "imageDirectory" preference. +# +############################################################################### + +have_imagedir=no +with_imagedir_req=unspecified + + +# Check whether --with-image-directory was given. +if test "${with_image_directory+set}" = set; then : + withval=$with_image_directory; with_imagedir="$withval"; with_imagedir_req="$withval" +else + with_imagedir=yes +fi + +# no HANDLE_X_PATH_ARG for this one + +case "$with_imagedir" in + /*) + # absolute path + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for image directory $with_imagedir" >&5 +$as_echo_n "checking for image directory $with_imagedir... " >&6; } + if test -d "$with_imagedir" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + with_imagedir="" + fi + ;; + yes) + with_imagedir="" + + #### Could use some more defaults here... + for dd in \ + "/usr/share/backgrounds/images/" \ + "/usr/share/wallpapers/" \ + "/Library/Desktop Pictures/" \ + ; do + if test -z "$with_imagedir"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for image directory $dd" >&5 +$as_echo_n "checking for image directory $dd... " >&6; } + if test -d "$dd" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + with_imagedir="$dd" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + done + + ;; + no) + with_imagedir="" + ;; + + *) + echo "error: must be an absolute path: --with-image-directory=$with_imagedir_req" + exit 1 + ;; +esac +ac_cv_imagedir="$with_imagedir" + +DEFAULT_IMAGES_P='True' +DEFAULT_IMAGE_DIRECTORY="$ac_cv_imagedir" + +if test -z "$DEFAULT_IMAGE_DIRECTORY" ; then + DEFAULT_IMAGES_P='False' +fi + + +############################################################################### +# +# Pick a text file to use as the default of the "textFile" preference. +# Any old file will do, but preferably one that will make interesting +# shapes when displayed by "starwars" and "fontglide". +# +############################################################################### + +have_textfile=no +with_textfile_req=unspecified + + +# Check whether --with-text-file was given. +if test "${with_text_file+set}" = set; then : + withval=$with_text_file; with_textfile="$withval"; with_textfile_req="$withval" +else + with_textfile=yes +fi + +# no HANDLE_X_PATH_ARG for this one + +case "$with_textfile" in + /*) + # absolute path + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for text file $with_textfile" >&5 +$as_echo_n "checking for text file $with_textfile... " >&6; } + if test -f "$with_textfile" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + with_textfile="" + fi + ;; + yes) + with_textfile="" + + #### Could use some more defaults here... + for f in \ + "/usr/X11R6/lib/X11/doc/README" \ + "/usr/share/doc/xserver-common/copyright" \ + "/usr/share/doc/xserver-xorg-core/copyright" \ + "/usr/X11R6/README" \ + "/usr/share/doc/libX11*/COPYING" \ + "/usr/X11/share/X11/doc/README*" \ + "/usr/share/doc/debian/debian-manifesto" \ + ; do + if test -z "$with_textfile"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for text file $f" >&5 +$as_echo_n "checking for text file $f... " >&6; } + f=`/bin/ls $f 2>&- | head -1` + if test -f "$f" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + with_textfile="$f" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + done + + ;; + no) + with_textfile="" + ;; + + *) + echo "error: must be an absolute path: --with-text-file=$with_textfile_req" + exit 1 + ;; +esac +ac_cv_textfile="$with_textfile" + +DEFAULT_TEXT_FILE="$ac_cv_textfile" + + +############################################################################### +# +# Check the browser to see help URL +# +############################################################################### + +have_browser=no +with_browser_req=unspecified + + +# Check whether --with-browser was given. +if test "${with_browser+set}" = set; then : + withval=$with_browser; with_browser="$withval"; with_browser_req="$withval" +else + with_browser=no +fi + +# no HANDLE_X_PATH_ARG for this one + +case "$with_browser" in + no ) + ;; + * ) + WITH_BROWSER=$with_browser + gnome_open_program=$with_browser + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for browser $with_browser" >&5 +$as_echo_n "checking for browser $with_browser... " >&6; } + with_browser_fullpath=`which $with_browser 2>/dev/null` + case $with_browser_fullpath in + /* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_browser=yes + ;; + * ) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +# Only warning: we don't want to install all packages for the +# dependency of the browser in building stage... + echo "WARNING: browser not found: --with-browser=$with_browser" + ;; + esac + ;; +esac +ac_cv_browser="$with_browser" + +############################################################################### +# +# Check whether it's ok to install some hacks as setuid (e.g., "sonar") +# This should be safe, but let's give people the option. +# +############################################################################### + +setuid_hacks_default=no +setuid_hacks="$setuid_hacks_default" + +# Check whether --with-setuid-hacks was given. +if test "${with_setuid_hacks+set}" = set; then : + withval=$with_setuid_hacks; setuid_hacks="$withval" +else + setuid_hacks="$setuid_hacks_default" +fi + + + + case "$setuid_hacks" in + yes) ;; + no) ;; + + /*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setuid hacks headers" >&5 +$as_echo_n "checking for setuid hacks headers... " >&6; } + d=$setuid_hacks/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setuid hacks libs" >&5 +$as_echo_n "checking for setuid hacks libs... " >&6; } + d=$setuid_hacks/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5 +$as_echo "$d" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found ($d: no such directory)" >&5 +$as_echo "not found ($d: no such directory)" >&6; } + fi + + # replace the directory string with "yes". + setuid_hacks_req="yes" + setuid_hacks=$setuid_hacks_req + ;; + + *) + echo "" + echo "error: argument to --with-setuid-hacks must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + + +if test "$setuid_hacks" = yes; then + true +elif test "$setuid_hacks" != no; then + echo "error: must be yes or no: --with-setuid-hacks=$setuid_hacks" + exit 1 +fi + + +############################################################################### +# +# Done testing. Now, set up the various -I and -L variables, +# and decide which GUI program to build by default. +# +############################################################################### + +DEPEND=makedepend +DEPEND_FLAGS= +DEPEND_DEFINES= + + +if test \! -z "$includedir" ; then + INCLUDES="$INCLUDES -I$includedir" +fi + +if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" +fi + + +PREFERRED_DEMO_PROGRAM='' +ALL_DEMO_PROGRAMS= +if test "$have_motif" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xm + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi +if test "$have_gtk" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Gtk + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi + + +if test "$have_kerberos" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(KERBEROS_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(KERBEROS_OBJS)" +fi +if test "$have_pam" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(PAM_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PAM_OBJS)" + INSTALL_PAM="install-pam" +fi +if test "$enable_pam_check_account_type" = yes; then + COMMENT_PAM_CHECK_ACCOUNT="" +else + COMMENT_PAM_CHECK_ACCOUNT="#" +fi +if test "$have_passwd_helper" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(PWHELPER_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PWHELPER_OBJS)" +fi + PASSWD_SRCS="$PASSWD_SRCS \$(PWENT_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PWENT_OBJS)" + + +if test "$enable_locking" = yes; then + LOCK_SRCS='$(LOCK_SRCS_1) $(PASSWD_SRCS)' + LOCK_OBJS='$(LOCK_OBJS_1) $(PASSWD_OBJS)' +else + LOCK_SRCS='$(NOLOCK_SRCS_1)' + LOCK_OBJS='$(NOLOCK_OBJS_1)' +fi + +if test "$ac_macosx" = yes; then + EXES_OSX='$(EXES_OSX)' + SCRIPTS_OSX='$(SCRIPTS_OSX)' + MEN_OSX='$(MEN_OSX)' +else + EXES_OSX= + SCRIPTS_OSX= + MEN_OSX= +fi + + +INSTALL_SETUID='$(INSTALL_PROGRAM) $(SUID_FLAGS)' + +if test "$need_setuid" = yes; then + NEED_SETUID=yes +else + NEED_SETUID=no +fi + +if test "$setuid_hacks" = yes; then + SETUID_HACKS=yes +else + SETUID_HACKS=no +fi + +tab=' ' +if test "$have_gl" = yes; then + GL_EXES='$(GL_EXES)' + SUID_EXES='$(SUID_EXES)' + RETIRED_GL_EXES='$(RETIRED_GL_EXES)' + GL_UTIL_EXES='$(GL_UTIL_EXES)' + GL_MEN='$(GL_MEN)' + GL_KLUDGE=" " +else + GL_KLUDGE="-" +fi + +if test "$have_gle" = yes; then + GLE_EXES='$(GLE_EXES)' + GLE_KLUDGE=" " +else + GLE_KLUDGE="-" +fi + +if test "$have_jpeg" = yes -a "$have_gdk_pixbuf" = yes; then + JPEG_EXES='$(JPEG_EXES)' +fi + + +# Another substitution in the XScreenSaver.ad.in file: +# +if test "$gnome_open_program" != ''; then + GNOME24='' + GNOME22='! ' + NOGNOME='! ' +elif test "$gnome_url_show_program" != ''; then + GNOME24='! ' + GNOME22='' + NOGNOME='! ' +else + GNOME24='! ' + GNOME22='! ' + NOGNOME='' +fi + + +# Set PO_DATADIR to something sensible. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for locale directory" >&5 +$as_echo_n "checking for locale directory... " >&6; } +if test -n "$GTK_DATADIR" ; then + PO_DATADIR="$GTK_DATADIR" +elif test "$have_gtk" = yes; then + PO_DATADIR=`$pkg_config --variable=prefix gtk+-2.0` + PO_DATADIR="$PO_DATADIR/share" +fi + +if test -z "$PO_DATADIR" ; then + # + # #### Total fucking kludge -- + # Map /build/prefix/usr/X11R6/share/ to /build/prefix/usr/share/ + # but of course we need to expand all the nested variables to do that... + # + dd=`eval eval eval eval eval eval eval eval eval eval eval echo $datadir` + PO_DATADIR=`echo $dd | sed 's@/X11R6/@/@'` +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PO_DATADIR/locale" >&5 +$as_echo "$PO_DATADIR/locale" >&6; } + + +# canonicalize slashes. +HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` + +# gcc 3.0 likes to issue this warning for every file: +# +# cc1: warning: changing search order for system directory "/usr/local/include" +# cc1: warning: as it has already been specified as a non-system directory +# +# Yay. We can only avoid that by deleting "-I${prefix}/include" from the list. +# Which *should* be totally redundant, and thus an ok thing to delete? +# +INCLUDES=`echo "$INCLUDES" | sed 's@ -I${prefix}/include@@g;'` + + +############################################################################### +# +# Perform substitutions and write Makefiles. +# +############################################################################### + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +APPDEFAULTS=$ac_x_app_defaults + + + + + + + +ac_config_files="$ac_config_files Makefile utils/Makefile driver/Makefile driver/xscreensaver.pam hacks/Makefile hacks/glx/Makefile po/Makefile.in driver/XScreenSaver.ad" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + + mv -f po/POTFILES po/POTFILES.tmp + sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +INTLTOOL_PERL=${INTLTOOL_PERL} + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "default-2") CONFIG_COMMANDS="$CONFIG_COMMANDS default-2" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "utils/Makefile") CONFIG_FILES="$CONFIG_FILES utils/Makefile" ;; + "driver/Makefile") CONFIG_FILES="$CONFIG_FILES driver/Makefile" ;; + "driver/xscreensaver.pam") CONFIG_FILES="$CONFIG_FILES driver/xscreensaver.pam" ;; + "hacks/Makefile") CONFIG_FILES="$CONFIG_FILES hacks/Makefile" ;; + "hacks/glx/Makefile") CONFIG_FILES="$CONFIG_FILES hacks/glx/Makefile" ;; + "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + "driver/XScreenSaver.ad") CONFIG_FILES="$CONFIG_FILES driver/XScreenSaver.ad" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "default-1":C) + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-extract.in > intltool-extract.out +if cmp -s intltool-extract intltool-extract.out 2>/dev/null; then + rm -f intltool-extract.out +else + mv -f intltool-extract.out intltool-extract +fi +chmod ugo+x intltool-extract +chmod u+w intltool-extract + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-merge.in > intltool-merge.out +if cmp -s intltool-merge intltool-merge.out 2>/dev/null; then + rm -f intltool-merge.out +else + mv -f intltool-merge.out intltool-merge +fi +chmod ugo+x intltool-merge +chmod u+w intltool-merge + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-update.in > intltool-update.out +if cmp -s intltool-update intltool-update.out 2>/dev/null; then + rm -f intltool-update.out +else + mv -f intltool-update.out intltool-update +fi +chmod ugo+x intltool-update +chmod u+w intltool-update + + ;; + "default-2":C) case "$CONFIG_FILES" in *po/Makefile.in*) + rm -f po/stamp-it po/stamp-it.tmp + > po/stamp-it.tmp + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + mv po/stamp-it.tmp po/stamp-it + esac ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +############################################################################### +# +# Print some warnings at the end. +# +############################################################################### + +warn_prefix_1=" Warning:" +warn_prefix_2=" Note:" +warn_prefix="$warn_prefix_1" + +warning=no +warnsep=' #################################################################' + +warnpre() { + if test "$warning" = no ; then + echo '' ; echo "$warnsep" ; echo '' + warning=yes + fi +} + +warn() { + warnpre + if test "$warning" = long ; then echo '' ; fi + warning=yes + rest="$@" + echo "$warn_prefix $rest" +} + +warnL() { + was=$warning + warnpre + warning=yes + if test "$was" != no ; then echo '' ; fi + rest="$@" + echo "$warn_prefix $rest" +} + +warn2() { + rest="$@" + echo " $rest" + warning=long +} + +note() { + warn_prefix="$warn_prefix_2" + warn $@ + warn_prefix="$warn_prefix_1" +} + +noteL() { + warn_prefix="$warn_prefix_2" + warnL $@ + warn_prefix="$warn_prefix_1" +} + + +if test "$with_sgi_req" = yes -a "$have_sgi" = no ; then + warn 'The SGI saver extension was requested, but was not found.' +fi + +if test "$with_xidle_req" = yes -a "$have_xidle" = no ; then + warn 'The XIdle extension was requested, but was not found.' +fi + +if test "$with_xshm_req" = yes -a "$have_xshm" = no ; then + warn 'The XSHM extension was requested, but was not found.' +fi + +if test "$with_xdbe_req" = yes -a "$have_xdbe" = no ; then + warn 'The DOUBLE-BUFFER extension was requested, but was not found.' +fi + +if test "$with_sgivc_req" = yes -a "$have_sgivc" = no ; then + warn 'The SGI-VIDEO-CONTROL extension was requested, but was not found.' +fi + +if test "$with_dpms_req" = yes -a "$have_dpms" = no ; then + warn 'The DPMS extension was requested, but was not found.' +fi + +if test "$with_xinerama_req" = yes -a "$have_xinerama" = no ; then + warn 'The Xinerama extension was requested, but was not found.' +fi + +if test "$with_xf86vmode_req" = yes -a "$have_xf86vmode" = no ; then + warn 'The XF86VMODE extension was requested, but was not found.' +fi + +if test "$with_randr_req" = yes -a "$have_randr" = no ; then + warn 'The RANDR extension was requested, but was not found.' +fi + +if test "$with_proc_interrupts_req" = yes -a "$have_proc_interrupts" = no; then + warn "Checking of /proc/interrupts was requested, but it's bogus." +fi + +if test "$pkg_config" = false ; then + warnL 'The "pkg-config" program was not found. Without that,' + warn2 "detection of the various GTK libraries won't work." +else + pkgerr=`$pkg_config --list-all 2>&1 >/dev/null` + if test "x$pkgerr" != "x" ; then + warnL 'The "pkg-config" program produces errors. This often causes' + warn2 "detection of the various GTK libraries to malfunction." + warn2 "The errors are:" + echo '' + echo "$pkgerr" | sed 's/^/ > /g' + fi +fi + +if test "$gtk_halfassed" != no ; then + warnL "GTK version $gtk_halfassed was found, but at least one supporting" + warn2 "library ($gtk_halfassed_lib) was not, so GTK can't be used." + warn2 "Perhaps some of the development packages are not installed?" + if test "$have_gtk" = yes ; then + v="$ac_gtk_version_string" + warn2 "GTK $v is also installed, so it will be used instead." + warn2 "Please read the above output and the \`config.log' file" + warn2 "for more details." + fi +fi + +motif_warn2() { + warn2 'Though the Motif front-end to xscreensaver is still' + warn2 'maintained, it is no longer being updated with new' + warn2 'features: all new development on the xscreensaver-demo' + warn2 'program is happening in the GTK version, and not in the' + warn2 'Motif version. It is recommended that you build against' + warn2 'GTK instead of Motif. See .' +} + +if test "$have_motif" = no -a "$have_gtk" = no; then + + if test "$with_motif" = yes; then + warnL "Neither the GTK nor Motif libraries were found; the" + warn2 "\`xscreensaver-demo' program requires one of these." + echo '' + motif_warn2 + else + warnL "The GTK libraries do not seem to be available; the" + warn2 "\`xscreensaver-demo' program requires them." +# echo '' +# warn2 'You can use Motif or Lesstif instead of GTK (use the' +# warn2 "\`--with-motif' option) but that is NOT recommended." +# motif_warn2 + fi + +elif test "$with_motif_req" = yes -a "$have_motif" = no ; then + warnL "Use of Motif was requested, but it wasn't found;" + warn2 "Gtk will be used instead." + +elif test "$jurassic_gtk" = yes ; then + + pref_gtk=2.0 + + v="$ac_gtk_version_string" + if test "$with_gtk_req" = yes -a "$ac_gtk_version" = "unknown" ; then + warnL "Use of Gtk was requested, but its version number is unknown;" + elif test "$with_gtk_req" = yes ; then + warnL "Use of Gtk was requested, but it is version $v;" + else + warnL "Gtk was found on this system, but it is version $v;" + fi + + warn2 "Gtk $pref_gtk or newer is required." + +elif test "$with_gtk_req" = yes -a "$have_gtk" = no ; then + warnL "Use of Gtk was requested, but it wasn't found." +fi + + +if test "$have_gtk" = yes -a "$have_gdk_pixbuf" = no ; then + warn "GTK is being used, but the GDK-Pixbuf library and/or" + warn2 "headers were not found. That can't be good. Please" + warn2 "install the GDK-Pixbuf development kit and re-configure." +fi + +if test "$have_motif" = yes -a "$have_lesstif" = yes ; then + + preferred_lesstif=0.92 + + if test "$lesstif_version" = unknown; then + warnL "Unable to determine the LessTif version number!" + warn2 "Make sure you are using version $preferred_lesstif or newer." + warn2 "See ." + + elif test \! $lesstif_version -gt 82; then + warnL "LessTif version $lesstif_version_string is being used." + warn2 "LessTif versions 0.82 and earlier are too buggy to" + warn2 "use with XScreenSaver; it is strongly recommended" + warn2 "that you upgrade to at least version $preferred_lesstif!" + warn2 "See ." + fi +fi + + +if test "$have_motif" = yes -a "$have_gtk" = no ; then + warn 'Motif is being used, and GTK is not.' + echo '' + motif_warn2 +fi + + +if test "$with_xpm_req" = yes -a "$have_xpm" = no; then + warnL 'Use of XPM was requested, but it was not found.' +fi + +if test "$with_gdk_pixbuf_req" = yes -a "$have_gdk_pixbuf" = no; then + warnL 'Use of GDK-Pixbuf was requested, but it was not found.' +fi + +if test "$have_gdk_pixbuf" = no -o "$gdk_pixbuf_halfassed" = yes || \ + test "$have_gdk_pixbuf" = no -a "$have_xpm" = no ; then + + if test "$with_gdk_pixbuf_req" = yes ; then + true + elif test "$with_gdk_pixbuf_req" = no ; then + warnL 'The GDK-Pixbuf library is not being used.' + else + warnL 'The GDK-Pixbuf library was not found.' + fi + + if test "$with_xpm_req" = yes -o "$have_xpm" = yes ; then + true + elif test "$with_xpm_req" = no ; then + warnL 'The XPM library is not being used.' + else + warnL 'The XPM library was not found.' + fi + + if test "$have_gdk_pixbuf" = no -a "$have_xpm" = yes ; then + warn2 'The XPM library is being used instead.' + fi + + if test "$gdk_pixbuf_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either GDK-Pixbuf is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 'Some of the demos will not use images as much as they could.' + warn2 'You should consider installing GDK-Pixbuf and re-running' + warn2 'configure. (GDK-Pixbuf is recommended over XPM, as it' + warn2 'provides support for more image formats.)' +fi + + +if test "$have_jpeg" = no ; then + if test "$with_jpeg_req" = yes ; then + warnL 'Use of libjpeg was requested, but it was not found.' + elif test "$with_jpeg_req" = no ; then + noteL 'The JPEG library is not being used.' + else + noteL 'The JPEG library was not found.' + fi + + if test "$jpeg_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'library; so either JPEG is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + echo '' + fi + + if test "$have_gdk_pixbuf" = no ; then + warn2 "This means that it won't be possible for the image-manipulating" + warn2 "display modes to load files from disk; and it also means that" + warn2 "the \`webcollage' program will be much slower." + else + warn2 "This means the \`webcollage' program will be much slower." + fi +fi + + +if test "$have_gl" = yes -a "$ac_have_mesa_gl" = yes ; then + preferred_mesagl=3.4 + mgv="$ac_mesagl_version_string" + pgl="$preferred_mesagl" + + if test "$ac_mesagl_version" = unknown; then + true + # warnL "Unable to determine the MesaGL version number!" + # warn2 "Make sure you are using version $preferred_mesagl or newer." + + elif test \! "$ac_mesagl_version" -gt 2006; then + warnL "MesaGL version number is $mgv --" + warn2 "MesaGL 2.6 and earlier have a security bug. It is strongly" + warn2 "recommended that you upgrade to at least version $preferred_mesagl." + + elif test \! "$ac_mesagl_version" -gt 3003; then + warnL "MesaGL version number is $mgv --" + warn2 "MesaGL 3.3 and earlier have some bugs; it is recommended" + warn2 "that you upgrade to $pgl or newer." + fi +fi + +if test "$have_gl" = no ; then + if test "$with_gl_req" = yes ; then + warnL 'Use of GL was requested, but it was not found.' + elif test "$with_gl_req" = no ; then + noteL 'The OpenGL 3D library is not being used.' + else + noteL 'The OpenGL 3D library was not found.' + fi + + if test "$gl_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either GL is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 'Those demos which use 3D will not be built or installed.' + warn2 'You might want to consider installing OpenGL and' + warn2 "re-running configure. If your vendor doesn't ship" + warn2 'their own implementation of OpenGL, you can get a free' + warn2 'version at . For general OpenGL' + warn2 'info, see .' + +fi + + +if test "$have_gl" = yes -a "$have_gle" = no ; then + + # nobody cares about this; don't print the warning unless it was + # requested and not found, or halfway-found. + if test "$with_gle_req" = yes -o "$gle_halfassed" = yes ; then + + if test "$with_gle_req" = yes ; then + noteL 'Use of the GLE (GL Extrusion) library was requested, but' + warn2 'it was not found (though the OpenGL library was found, and' + warn2 'is being used.)' + elif test "$with_gle_req" = no ; then + noteL 'The OpenGL Library is being used, but the GLE (GL Extrusion)' + warn2 'library is not.' + else + noteL 'The OpenGL Library was found, but the GLE (GL Extrusion)' + warn2 'was not.' + fi + + if test "$gle_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either GLE is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 'Some of the OpenGL (3D) demos (those that depend on GLE)' + warn2 'will not be built or installed. You might want to consider' + warn2 'installing GLE and re-running configure. You can find the' + warn2 'GLE library at . For general' + warn2 'OpenGL info, see .' + + fi +fi + + +if test "$with_readdisplay_req" = yes -a "$have_readdisplay" = no ; then + warn 'Use of XReadDisplay was requested, but it was not found.' +fi + +if test "$with_kerberos_req" = yes -a "$have_kerberos" = no ; then + warn 'Use of Kerberos was requested, but it was not found.' +fi + +if test "$with_pam_req" = yes -a "$have_pam" = no ; then + warn 'Use of PAM was requested, but it was not found.' +fi + +if test "$with_shadow_req" = yes -a "$have_shadow" = no ; then + warn 'Use of shadow passwords was requested, but they were not found.' +fi + +if test "$ac_macosx" = yes ; then + if test "$enable_locking" = yes ; then + warn "You have specified --enable-locking on MacOS X." + warn2 "THIS DOES NOT WORK! Don't do this!" + fi +fi + + +# You are in a twisty maze of namespaces and syntaxes, all alike. +# Fuck the skull of Unix. +# +bindir=`eval eval eval eval eval eval eval echo $bindir` +HACKDIR=`eval eval eval eval eval eval eval echo $HACKDIR` +HACK_CONF_DIR=`eval eval eval eval eval eval eval echo $HACK_CONF_DIR` + +# canonicalize slashes. +bindir=`echo "${bindir}" | sed 's@/$@@;s@//*@/@g'` +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` +HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` + + +# Sanity check the hackdir +for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do + if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then + echo "" + as_fn_error $? "\"--with-hackdir=${bindir}/${bad_choice}\" won't work. + There will be an executable installed with that name, so + that can't be the name of a directory as well. Please + re-configure with a different directory name." "$LINENO" 5 + fi +done + + +do_dir_warning=no + +# Now let's warn if there's a previous RPM version already installed. +# But don't bother with this test if we are currently *building* an RPM. + +if test -z "$RPM_PACKAGE_VERSION" ; then + + rpmnames="xscreensaver xscreensaver-base xscreensaver-extras" + + # M4 sucks!! + + rpmv=`(rpm -qv $rpmnames) 2>/dev/null | \ + sed -n 's/^[-a-z]*-\([0-9][0-9]*[.][0-9][0-9a-z]*\)-.*$/\1/p' | \ + head -1` + + + if test \! -z "$rpmv" ; then + rpmbdir=`rpm -ql $rpmnames | sed -n 's@^\(.*\)/xscreensaver-demo$@\1@p'` + rpmhdir=`rpm -ql $rpmnames | sed -n 's@^\(.*\)/popsquares$@\1@p'` + + warning=no + warnL "There is already an installed RPM of xscreensaver $rpmv" + warn2 'on this system. You might want to remove it ("rpm -ve")' + warn2 'before running "make install" in this directory.' + echo "" + warn2 "Alternately, you could build this version of xscreensaver" + warn2 'as an RPM, and then install that. An "xscreensaver.spec"' + warn2 'file is included. Try "rpmbuild -v -ba xscreensaver.spec".' + warn2 "See the RPM documentation for more info." + echo "" + + if test "$rpmbdir" = "$rpmhdir" ; then + warn2 "The RPM version was installed in $rpmbdir/." + do_dir_warning=yes + else + warn2 "The RPM version was installed in $rpmbdir/," + warn2 "with demos in $rpmhdir/." + fi + fi +fi + +# Also warn if there's a Debian package installed. +# +debnames="xscreensaver xscreensaver-data xscreensaver-data-extra" +debv='' +for dpkg in $debnames ; do + if test -z "$debv"; then + debv=`dpkg -s $dpkg 2>/dev/null | sed -n 's/^Version: \(.*\)$/\1/p'` + fi +done + +if test \! -z "$debv" ; then + debbdir=`dpkg -L $debnames 2>/dev/null | \ + sed -n 's@^\(.*/bin/\)xscreensaver$@\1@p'` + debhdir=`dpkg -L $debnames 2>/dev/null | \ + sed -n 's@^\(.*/\)popsquares$@\1@p'` + if test -z "$debbdir" ; then debbdir='???'; fi + if test -z "$debhdir" ; then debhdir='???'; fi + + warning=no + warnL "There is already an installed dpkg of xscreensaver" + warn2 "version \"$debv\" on this system." + echo "" + warn2 "The dpkg was installed in $debbdir," + warn2 "with demos in $debhdir." +fi + + +if test "${bindir}" = "${HACKDIR}" ; then + do_dir_warning=yes +fi + +if test "$do_dir_warning" = yes; then + echo "" + echo "$warnsep" + echo "" + echo ' When you run "make install", the "xscreensaver",' + echo ' "xscreensaver-demo", and "xscreensaver-command" executables' + echo " will be installed in ${bindir}/." + echo "" + echo " The various graphics demos (190+ different executables) will" + echo " be installed in ${HACKDIR}/." + echo "" + echo " If you would prefer the demos to be installed elsewhere," + echo " you should re-run configure with the --with-hackdir=DIR" + echo " option. For more information, run \`./configure --help'." + warning=yes +fi + +if test "$warning" != no; then + echo '' ; echo "$warnsep" ; echo '' +fi + +if test "$do_dir_warning" = no; then + if test "$warning" = no; then + echo '' + fi + echo "User programs will be installed in ${bindir}/" + echo "Screen savers will be installed in ${HACKDIR}/" + echo "Configuration dialogs will be installed in ${HACK_CONF_DIR}/" + echo "System-wide default settings will be installed in ${APPDEFAULTS}/" + echo '' +fi diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..74887955 --- /dev/null +++ b/configure.in @@ -0,0 +1,4465 @@ +# configure.in --- xscreensaver, Copyright (c) 1997-2005 Jamie Zawinski. +# + +AC_PREREQ(2.52) +AC_INIT(driver/subprocs.c) +AC_CONFIG_HEADER(config.h) + +echo "current directory: `pwd`" +echo "command line was: $0 $@" + +############################################################################### +# +# Autoheader stuff +# +############################################################################### + +AH_TOP([ +/* config.h.in --- xscreensaver, Copyright (c) 1998-2000 Jamie Zawinski. + * + * The best way to set these parameters is by running the included `configure' + * script. That examines your system, and generates `config.h' from + * `config.h.in'. + * + * If something goes very wrong, you can edit `config.h' directly, but beware + * that your changes will be lost if you ever run `configure' again. + */ +]) + +AH_TEMPLATE([HAVE_READ_DISPLAY_EXTENSION], + [Define this if you have the XReadDisplay extension (I think + this is an SGI-only thing; it's in + .) A few of the screenhacks will + take advantage of this if it's available.]) + +AH_TEMPLATE([HAVE_XHPDISABLERESET], + [Define this if you have the XHPDisableReset function (an HP only + thing which allows the Ctrl-Sh-Reset key sequence to be + temporarily disabled.)]) + +# This only ever existed in X11R4 and X11R5. +#AH_TEMPLATE([HAVE_XIDLE_EXTENSION], +# [Define this if you have the XIDLE extension installed. If you +# have the XIDLE extension, this is recommended. (You have this +# extension if the file /usr/include/X11/extensions/xidle.h +# exists.) Turning on this flag lets XScreenSaver work better with +# servers which support this extension; but it will still work +# with servers which do not suport it, so it's a good idea to +# compile in support for it if you can.]) + +# Using this extension will crash your X server and make fading not work. +#AH_TEMPLATE([HAVE_MIT_SAVER_EXTENSION], +# [Define this if you have the MIT-SCREEN-SAVER extension +# installed. See the caveats about this extension, above. +# (It's available if /usr/include/X11/extensions/scrnsaver.h +# exists.)]) + +# This only ever existed on SGI hardware. +#AH_TEMPLATE([HAVE_SGI_SAVER_EXTENSION], +# [Define this if you have the SGI SCREEN_SAVER extension. This is +# standard on Irix systems, and not available elsewhere.]) + +# This only ever existed on SGI hardware. +#AH_TEMPLATE([HAVE_SGI_VC_EXTENSION], +# [Define this if you have the SGI-VIDEO-CONTROL extension. This +# is standard on Irix systems, and not available elsewhere.]) + +AH_TEMPLATE([HAVE_DPMS_EXTENSION], + [Define this if you have the XDPMS extension. This is standard + on sufficiently-recent XFree86 systems, and possibly elsewhere. + (It's available if the file /usr/include/X11/extensions/dpms.h + exists.)]) + +AH_TEMPLATE([HAVE_XF86VMODE], + [Define this if you have the functions XF86VidModeGetModeLine() + and XF86VidModeGetViewPort(), in support of virtual desktops + where the X server's root window is bigger than the actual + screen. This is an XFree86 thing, and probably doesn't exist + elsewhere. (It's available if the file + /usr/include/X11/extensions/xf86vmode.h exists.)]) + +AH_TEMPLATE([HAVE_XF86VMODE_GAMMA], + [Define this if you have the functions XF86VidModeGetGamma() and + XF86VidModeSetGamma(), which allow clients to change the gamma + response of the monitor. This is an XFree86 4.0.x thing, and + probably doesn't exist elsewhere. (It's available if the file + /usr/include/X11/extensions/xf86vmode.h exists and has stuff about + gamma in it.)]) + +AH_TEMPLATE([HAVE_XF86VMODE_GAMMA_RAMP], + [Define this if you have the functions XF86VidModeGetGammaRamp() + and XF86VidModeSetGammaRamp(), which provide finer-grained + control than XF86VidMode[GS]etGamma(). These appeared in + XFree86 4.1.0.]) + +AH_TEMPLATE([HAVE_XINERAMA], + [Define this if you have the Xinerama extension. This is + standard on sufficiently-recent XFree86 systems, and possibly + elsewhere. (It's available if the file + /usr/include/X11/extensions/Xinerama.h exists.)]) + +AH_TEMPLATE([HAVE_XINPUT], + [Define this if you have the Xinput extension. This is + standard since X11R5, and is thus almost everywhere. + (It's available if the file /usr/include/X11/extensions/XInput.h + exists.)]) + +AH_TEMPLATE([HAVE_XF86MISCSETGRABKEYSSTATE], + [Define this if you have the XF86MiscSetGrabKeysState function + (which allows the Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash key + sequences to be temporarily disabled. Sadly, it doesn't affect + Ctrl-Alt-BS or Ctrl-Alt-F1.)]) + +AH_TEMPLATE([HAVE_RANDR], + [Define this if you have the Resize and Rotate extension. + This is standard on sufficiently-recent XFree86 systems, and + possibly elsewhere. (It's available if the file + /usr/include/X11/extensions/Xrandr.h exists.)]) + +AH_TEMPLATE([HAVE_RANDR_12], + [Define this if the RANDR library is version 1.2 or newer.]) + +AH_TEMPLATE([HAVE_PROC_INTERRUPTS], + [Define this if you have a Linux-like /proc/interrupts file which + can be examined to determine when keyboard activity has + occurred.]) + +AH_TEMPLATE([HAVE_MOTIF],[Define this if you have Motif.]) + +AH_TEMPLATE([HAVE_XMCOMBOBOX], + [Define this if you have the XmComboBox Motif widget (Motif 2.0.)]) + +AH_TEMPLATE([HAVE_GTK],[Define this if you have Gtk (any version.)]) +AH_TEMPLATE([HAVE_GTK2],[Define this if you have Gtk 2.x.]) + +AH_TEMPLATE([HAVE_CRAPPLET], + [Define this if you have Gnome and want to build support for the + xscreensaver control panel in the Gnome Control Center + (gnomecc). (This is needed only with Gtk 1.x.)]) + +AH_TEMPLATE([HAVE_CRAPPLET_IMMEDIATE], + [Define this if HAVE_CRAPPLET is defined, and the function + capplet_widget_changes_are_immediate() is available.]) + +AH_TEMPLATE([HAVE_XML],[Define this if you have the XML library.]) + +AH_TEMPLATE([HAVE_OLD_XML_HEADERS], + [Define this if you have the XML library headers in their old, + non-namespaced location (you lack the gnome-xml/libxml symlink)]) + +AH_TEMPLATE([HAVE_XPM], + [Define this if you have the XPM library installed. Some of the + demos can make use of this if it is available.]) + +AH_TEMPLATE([HAVE_GDK_PIXBUF], + [Define this if you have the GDK_Pixbuf library installed. Some + of the demos can make use of this if it is available.]) + +AH_TEMPLATE([HAVE_GDK_PIXBUF_APPLY_EMBEDDED_ORIENTATION], + [Define this if you have the gdk_pixbuf_apply_embedded_orientation + function (gdk-pixbuf 2.12).]) + +AH_TEMPLATE([HAVE_JPEGLIB], + [Define this if you have the Independent JPEG Group's JPEG + library installed. Some of the demos can make use of this if it + is available.]) + +AH_TEMPLATE([HAVE_XMU], + [Define this if you have the Xmu library. This is standard part + of X, and if your vendor doesn't ship it, you should report that + as a bug.]) + +AH_TEMPLATE([HAVE_GL], + [Define this if you have OpenGL. Some of the demos require it, + so if you don't have it, then those particular demos won't be + built. (This won't affect the screen saver as a whole.)]) + +AH_TEMPLATE([HAVE_MESA_GL], + [Define this if you have OpenGL, but it's the MesaGL variant. + (The libraries have different names.) (HAVE_GL should be defined + too.)]) + +AH_TEMPLATE([HAVE_GLBINDTEXTURE], + [Define this if your version of OpenGL has the glBindTexture() + routine. This is the case for OpenGL 1.1, but not for OpenGL + 1.0.]) + +AH_TEMPLATE([HAVE_GLE], + [Define this if you have the -lgle and -lmatrix libraries (GL + extrusion.)]) + +AH_TEMPLATE([HAVE_GLE3],[Define this if you have the -lgle from GLE version 3]) + +AH_TEMPLATE([HAVE_JWZGLES],[Define this to target the OpenGL ES 1.x API + instead of OpenGL 1.3.]) + +AH_TEMPLATE([HAVE_GLBITMAP],[Define this if glBitmap exists.]) + +AH_TEMPLATE([HAVE_XSHM_EXTENSION], + [Define this if you have the X Shared Memory Extension.]) + +AH_TEMPLATE([HAVE_DOUBLE_BUFFER_EXTENSION], + [Define this if you have the X Double Buffer Extension.]) + +AH_TEMPLATE([FORTUNE_PROGRAM], + [Some screenhacks like to run an external program to generate + random pieces of text; set this to the one you like. Note that + this is just the default; X resources can be used to override + it.]) + +AH_TEMPLATE([PASSWD_HELPER_PROGRAM], + [Set the name of the password helper program, if any]) + +AH_TEMPLATE([NO_LOCKING], + [Define this to remove the option of locking the screen at all.]) + +AH_TEMPLATE([ALLOW_ROOT_PASSWD], + [Define this to allow the root password to unlock the screen.]) + +AH_TEMPLATE([HAVE_KERBEROS], + [Define this if you want to use Kerberos authentication to + lock/unlock the screen instead of your local password. This + currently uses Kerberos V4, but a V5 server with V4 + compatibility will work. WARNING: DO NOT USE AFS string-to-key + passwords with this option. This option currently *only* works + with standard Kerberos des_string_to_key. If your password is + an AFS password and not a kerberos password, it will not + authenticate properly. See the comments in driver/kpasswd.c for + more information if you need it.]) + +AH_TEMPLATE([HAVE_KERBEROS5], + [Define this if you have Kerberos 5, meaning we need to use the + Kerberos 4 compatibility layer.]) + +AH_TEMPLATE([HAVE_PAM], + [Define this if you want to use PAM (Pluggable Authentication + Modules) to lock/unlock the screen, instead of standard + /etc/passwd authentication.]) + +AH_TEMPLATE([PAM_SERVICE_NAME], + [If PAM is being used, this is the name of the PAM service that + xscreensaver will authenticate as. The default is + "xscreensaver", which means that the PAM library will look for + an "xscreensaver" line in /etc/pam.conf, or (on recent Linux + systems) will look for a file called /etc/pam.d/xscreensaver. + Some systems might already have a PAM installation that is + configured for xlock, so setting this to "xlock" would also work + in that case.]) + +AH_TEMPLATE([HAVE_PAM_FAIL_DELAY], + [Define this if you have pam_fail_delay function. + see driver/passwd-pam.c.]) + +AH_TEMPLATE([PAM_CHECK_ACCOUNT_TYPE], + [Whether PAM should check the result of account modules + when authenticating. Only do this if you have account + configured properly on your system.]) + +AH_TEMPLATE([PAM_STRERROR_TWO_ARGS], + [Define if you have PAM and pam_strerror() requires two + arguments.]) + +AH_TEMPLATE([HAVE_SIGTIMEDWAIT], + [Define to 1 if you have the `sigtimedwait' function.]) + +AH_TEMPLATE([HAVE_SHADOW_PASSWD], + [Define this if your system uses 'shadow' passwords, that is, the + passwords live in /etc/shadow instead of /etc/passwd, and one + reads them with getspnam() instead of getpwnam(). (Note that + SCO systems do some random other thing; others might as well. + See the ifdefs in driver/passwd-pwent.c if you're having trouble + related to reading passwords.)]) + +AH_TEMPLATE([HAVE_ENHANCED_PASSWD], + [Define this if your system is Digital or SCO Unix with so-called + ``Enhanced Security'', that is, the passwords live in + /tcb/files/auth// instead of in /etc/passwd, and one + reads them with getprpwnam() instead of getpwnam().]) + +AH_TEMPLATE([HAVE_ADJUNCT_PASSWD], + [Define this if your system is Solaris with ``adjunct'' passwords + (this is the version where one gets at the passwords with + getpwanam() instead of getpwnam().) I haven't tested this one, + let me know if it works.]) + +AH_TEMPLATE([HAVE_HPUX_PASSWD], + [Define this if you are running HPUX with so-called ``Secure + Passwords'' (if you have /usr/include/hpsecurity.h, you probably + have this.) I haven't tested this one, let me know if it works.]) + +AH_TEMPLATE([HAVE_SYSLOG], + [Define this if you the openlog(), syslog(), and closelog() + functions. This is used for logging failed login attempts.]) + +AH_TEMPLATE([HAVE_ICMP], + [Define this if you do pings with a `struct icmp' and an + `icmp_id' slot.]) + +AH_TEMPLATE([HAVE_ICMPHDR], + [Define this if you do pings with a `struct icmphdr' and an + `un.echo.id' slot.]) + +AH_TEMPLATE([HAVE_GETIFADDRS], + [Define this if you have the getifaddrs() function.]) + +AH_TEMPLATE([HAVE_FORKPTY], + [Define this if you have the 'forkpty' function: + This allows 'phosphor' and 'apple2' to run curses-based + programs, or be used as terminal windows.]) + +AH_TEMPLATE([HAVE_GETTIMEOFDAY], + [Define this if you have the gettimeofday function.]) + +AH_TEMPLATE([GETTIMEOFDAY_TWO_ARGS], + [Define this if gettimeofday() takes two arguments.]) + +AH_TEMPLATE([XPointer], + [Define this to void* if you're using X11R4 or earlier.]) + +# After checking to see that --srcdir is correct (which AC_INIT does) +# check for some random other files that come later in the tar file, +# to make sure everything is here. +# +for d in driver utils hacks hacks/glx ; do + f=$srcdir/$d/Makefile.in + if test \! -r $f ; then + echo "" + echo "ERROR: The package is incomplete: $f does not exist." + echo " This probably means that your download was truncated." + echo "" + exit 1 + fi +done + +############################################################################### +# +# Function to figure out how to run the compiler. +# +############################################################################### + +AC_DEFUN(AC_PROG_CC_ANSI, + [AC_REQUIRE([AC_PROG_CC]) + + if test -z "$GCC"; then + # not using GCC + AC_MSG_CHECKING(how to request ANSI compilation) + case "$host" in + *-hpux* ) + AC_MSG_RESULT(HPUX: adding -Ae) + CC="$CC -Ae" + ;; + *-aix* ) + AC_MSG_RESULT(AIX: adding -qlanglvl=ansi -qhalt=e) + CC="$CC -qlanglvl=ansi -qhalt=e" + ;; + *-dec-* ) + AC_MSG_RESULT(DEC: adding -std1 -ieee) + CC="$CC -std1" + ;; + *) + AC_MSG_RESULT(no idea) + ;; + esac + else + # using GCC + case "$host" in + *-solaris*) + AC_MSG_RESULT(Solaris: adding -D__EXTENSIONS__) + CC="$CC -D__EXTENSIONS__" + ;; + esac + fi + + OBJCC="$CC" + + AC_MSG_CHECKING([whether the compiler works on ANSI C]) + AC_TRY_RUN([ main(int ac, char **av) { return 0; } ], + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no) + AC_MSG_ERROR(Couldn't build even a trivial ANSI C program: check CC.), + AC_MSG_ERROR(Couldn't build even a trivial ANSI C program: check CC.)) + + if test -n "$GCC"; then + AC_MSG_RESULT(Turning on gcc compiler warnings.) + CC="$CC -pedantic -Wall -Wstrict-prototypes -Wnested-externs -Wmissing-prototypes" + OBJCC="$OBJCC -Wall" + # As of gcc 3.4, we have "-Wdeclaration-after-statement" + # and so perhaps now we can do without -pedantic? + else + case "$host" in + *-irix5* |*-irix6.[0-3]* ) + AC_MSG_RESULT(Turning on SGI compiler warnings.) + CC="$CC -fullwarn -use_readonly_const -rdata_shared -g3" + ;; +# *-dec-osf* ) +# if test -z "$GCC"; then +# AC_MSG_RESULT(Turning on DEC C compiler warnings.) +# CC="$CC -migrate -w0 -verbose -warnprotos" +# fi +# ;; + esac + fi +]) + + +############################################################################### +# +# Check for availability of various gcc command-line options. +# +############################################################################### + +AC_DEFUN(AC_CHECK_GCC_ARG, + [if test -n "$GCC"; then + AC_CACHE_CHECK([whether gcc accepts [$2]], + ac_cv_gcc_accepts_[$1], + [rm -rf conftest.$ac_ext + touch conftest.$ac_ext + if ( ( gcc -c [$2] conftest.$ac_ext -o/dev/null >/dev/null ) 2>&1 | \ + grep unrecognized >/dev/null ); then + ac_cv_gcc_accepts_[$1]=no + else + ac_cv_gcc_accepts_[$1]=yes + CC="$CC [$2]" + fi]) + ac_gcc_accepts_[$1]="$ac_cv_gcc_accepts_[$1]" + fi +]) + +AC_DEFUN(AC_NO_LONG_STRING_WARNINGS, + [AC_CHECK_GCC_ARG(no_overlength, -Wno-overlength-strings)]) + +AC_DEFUN(AC_NO_MISPLACED_DECLARATIONS, + [AC_CHECK_GCC_ARG(no_decl_after, -Wdeclaration-after-statement)]) + +# Need to disable Objective C extensions in ANSI C on MacOS X to work +# around an Apple-specific gcc bug. +# +AC_DEFUN(AC_NO_OBJECTIVE_C, + [AC_CHECK_GCC_ARG(no_cpp_precomp, -no-cpp-precomp)]) + +############################################################################### +# +# Function to figure out how to disable // comments in ANSI C code. +# +# (With recent gcc, this is done with "-std=c89". With older gcc, this +# is done by passing "-lang-c89" to cpp, by passing "-Wp,-lang-c89" to +# gcc. Old gcc doesn't support -std, and new gcc doesn't support -lang. +# so much for compatibility!) +# +# UPDATE: apparently there is NO WAY to tell gcc 3.2.2 to require that +# declarations preceed statements, without resorting to "-pedantic". +# This means that there is no way to get gcc3 to issue warnings that +# ensure that your code complies with the ANSI/ISO C89 standard, without +# also drowning in totally useless warnings. Thank you master may I +# have another. +# +# So, I give up, let's just use -pedantic. +# +############################################################################### + +AC_DEFUN(AC_GCC_ACCEPTS_STD, [ + case "$host" in + *-darwin* ) + # Fucking Apple let // comments sneak into OpenGL headers, so + # we *must* allow // comments when compiling on Mac OS 10.6! FUCK! + ;; + *) + AC_CHECK_GCC_ARG(std, -std=c89) + ;; + esac +]) + +AC_DEFUN(AC_NO_CPLUSPLUS_COMMENTS_IN_C_CODE, + [if test -n "$GCC"; then + AC_GCC_ACCEPTS_STD + AC_MSG_RESULT(Disabling C++ comments in ANSI C code.) + # + # The reason that // comments are banned from xscreensaver is that gcc is + # basically the only compiler in the world that supports them in C code. + # All other vendors support them only in their C++ compilers, not in their + # ANSI C compilers. This means that it's a portability problem: every time + # these comments have snuck into the xscreensaver source code, I've gotten + # complaints about it the next day. So we turn off support for them in gcc + # as well to prevent them from accidentially slipping in. + # + if test "$ac_gcc_accepts_std" = yes ; then + # + # -std=c89 defines __STRICT_ANSI__, which we don't want. + # (That appears to be the only additional preprocessor symbol + # it defines, in addition to the syntax changes it makes.) + # + # -std=gnu89 is no good, because // comments were a GNU extension + # before they were in the ANSI C 99 spec... (gcc 2.96 permits // + # with -std=gnu89 but not with -std=c89.) + # + # $CC already contains "-std=c89" via AC_GCC_ACCEPTS_STD + CC="$CC -U__STRICT_ANSI__" +# else +# # The old way: +# CC="$CC -Wp,-lang-c89" + fi + fi +]) + + +############################################################################### +# +# Function to figure out how to create directory trees. +# +############################################################################### + +AC_DEFUN(AC_PROG_INSTALL_DIRS, + [AC_CACHE_CHECK([whether "\${INSTALL} -d" creates intermediate directories], + ac_cv_install_d_creates_dirs, + [ac_cv_install_d_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir 2>/dev/null + ${INSTALL} -d `pwd`/dir1/dir2 >/dev/null 2>&1 + if test -d dir1/dir2/. ; then + ac_cv_install_d_creates_dirs=yes + fi + cd .. 2>/dev/null + rm -rf conftestdir + fi + ]) + + if test "$ac_cv_install_d_creates_dirs" = no ; then + AC_CACHE_CHECK([whether "mkdir -p" creates intermediate directories], + ac_cv_mkdir_p_creates_dirs, + [ac_cv_mkdir_p_creates_dirs=no + rm -rf conftestdir + if mkdir conftestdir; then + cd conftestdir 2>/dev/null + mkdir -p dir1/dir2 >/dev/null 2>&1 + if test -d dir1/dir2/. ; then + ac_cv_mkdir_p_creates_dirs=yes + fi + cd .. 2>/dev/null + rm -rf conftestdir + fi + ]) + fi + + if test "$ac_cv_install_d_creates_dirs" = yes ; then + INSTALL_DIRS='${INSTALL} -d' + elif test "$ac_cv_mkdir_p_creates_dirs" = yes ; then + INSTALL_DIRS='mkdir -p' + else + # any other ideas? + INSTALL_DIRS='${INSTALL} -d' + fi +]) + + +############################################################################### +# +# Function to check whether gettimeofday() exists, and how to call it. +# This may define HAVE_GETTIMEOFDAY and GETTIMEOFDAY_TWO_ARGS. +# +############################################################################### + +AC_DEFUN(AC_GETTIMEOFDAY_ARGS, + [AC_MSG_CHECKING(how to call gettimeofday) + AC_CACHE_VAL(ac_cv_gettimeofday_args, + [AC_TRY_COMPILE([#include + #include ], + [struct timeval tv; struct timezone tzp; + gettimeofday(&tv, &tzp);], + [ac_gettimeofday_args=2], + [AC_TRY_COMPILE([#include + #include ], + [struct timeval tv; gettimeofday(&tv);], + [ac_gettimeofday_args=1], + [ac_gettimeofday_args=0])]) + ac_cv_gettimeofday_args=$ac_gettimeofday_args]) + ac_gettimeofday_args=$ac_cv_gettimeofday_args + if test "$ac_gettimeofday_args" = 1 ; then + AC_DEFINE(HAVE_GETTIMEOFDAY) + AC_MSG_RESULT(one argument) + elif test "$ac_gettimeofday_args" = 2 ; then + AC_DEFINE(HAVE_GETTIMEOFDAY) + AC_DEFINE(GETTIMEOFDAY_TWO_ARGS) + AC_MSG_RESULT(two arguments) + else + AC_MSG_RESULT(unknown) + fi +]) + + +############################################################################### +# +# Function to find perl5 (defines PERL and PERL_VERSION.) +# +############################################################################### + +# M4 sucks!! perl sucks too!! +changequote(X,Y) +perl_version_cmd='print $]' +changequote([,]) + +AC_DEFUN(AC_PROG_PERL, + [AC_PATH_PROGS(PERL, [perl5 perl],,) + if test -z "$PERL" ; then + PERL_VERSION=0 + else + AC_CACHE_CHECK([perl version], ac_cv_perl_version, + [ac_cv_perl_version=`$PERL -e "$perl_version_cmd"`]) + PERL_VERSION=$ac_cv_perl_version + fi + ]) + + +############################################################################### +# +# Function to demand "bc". Losers. +# +############################################################################### + +AC_DEFUN(AC_DEMAND_BC, + [ac_bc_result=`echo 6+9 | bc 2>/dev/null` + AC_MSG_CHECKING([for bc]) + if test "$ac_bc_result" = "15" ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + echo '' + AC_MSG_ERROR([Your system doesn't have \"bc\", which has been a standard + part of Unix since the 1970s. Come back when your vendor + has grown a clue.]) + fi + ]) + +############################################################################### +# +# Functions to check how to do ICMP PING requests. +# +############################################################################### + +AC_DEFUN(AC_CHECK_ICMP, + [AC_CACHE_CHECK([for struct icmp], ac_cv_have_icmp, + [AC_TRY_COMPILE([#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include ], + [struct icmp i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.icmp_type = ICMP_ECHO; + i.icmp_code = 0; + i.icmp_cksum = 0; + i.icmp_id = 0; + i.icmp_seq = 0; + si.sin_family = AF_INET; + #if defined(__DECC) || defined(_IP_VHL) + ip.ip_vhl = 0; + #else + ip.ip_hl = 0; + #endif + ], + [ac_cv_have_icmp=yes], + [ac_cv_have_icmp=no])]) + if test "$ac_cv_have_icmp" = yes ; then + AC_DEFINE(HAVE_ICMP) + fi]) + +AC_DEFUN(AC_CHECK_ICMPHDR, + [AC_CACHE_CHECK([for struct icmphdr], ac_cv_have_icmphdr, + [AC_TRY_COMPILE([#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include ], + [struct icmphdr i; + struct sockaddr s; + struct sockaddr_in si; + struct ip ip; + i.type = ICMP_ECHO; + i.code = 0; + i.checksum = 0; + i.un.echo.id = 0; + i.un.echo.sequence = 0; + si.sin_family = AF_INET; + ip.ip_hl = 0;], + [ac_cv_have_icmphdr=yes], + [ac_cv_have_icmphdr=no])]) + if test "$ac_cv_have_icmphdr" = yes ; then + AC_DEFINE(HAVE_ICMPHDR) + fi]) + + +############################################################################### +# +# Functions to check for various X11 crap. +# +############################################################################### + +# Try and find the app-defaults directory. +# It sucks that autoconf doesn't do this already... +# +AC_DEFUN(AC_PATH_X_APP_DEFAULTS_XMKMF,[ + rm -fr conftestdir + if mkdir conftestdir; then + cd conftestdir 2>/dev/null + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_x_app_defaults="${XAPPLOADDIR}"' +EOF + if (xmkmf) >/dev/null 2>&1 && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which'd confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + fi + cd .. 2>/dev/null + rm -fr conftestdir + fi]) + +############################################################################### +# +# Handle the --with-x-app-defaults option HERE +# +############################################################################### + +AC_ARG_WITH(x-app-defaults,[], + [ac_cv_x_app_defaults="$withval"], + [eval ac_x_app_defaults="$withval"]) + + +AC_DEFUN(AC_PATH_X_APP_DEFAULTS_DIRECT,[ + # Look for the directory under a standard set of common directories. + # Check X11 before X11Rn because it's often a symlink to the current release. + for ac_dir in \ + /usr/X11/lib/app-defaults \ + /usr/X11R6/lib/app-defaults \ + /usr/X11R6/lib/X11/app-defaults \ + /usr/X11R5/lib/app-defaults \ + /usr/X11R5/lib/X11/app-defaults \ + /usr/X11R4/lib/app-defaults \ + /usr/X11R4/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/lib/X11R6/app-defaults \ + /usr/lib/X11R5/app-defaults \ + /usr/lib/X11R4/app-defaults \ + \ + /usr/local/X11/lib/app-defaults \ + /usr/local/X11R6/lib/app-defaults \ + /usr/local/X11R5/lib/app-defaults \ + /usr/local/X11R4/lib/app-defaults \ + \ + /usr/local/lib/X11/app-defaults \ + /usr/local/lib/X11R6/app-defaults \ + /usr/local/lib/X11R6/X11/app-defaults \ + /usr/local/lib/X11R5/app-defaults \ + /usr/local/lib/X11R5/X11/app-defaults \ + /usr/local/lib/X11R4/app-defaults \ + /usr/local/lib/X11R4/X11/app-defaults \ + \ + /usr/X386/lib/X11/app-defaults \ + /usr/x386/lib/X11/app-defaults \ + /usr/XFree86/lib/X11/app-defaults \ + \ + /usr/lib/X11/app-defaults \ + /usr/local/lib/X11/app-defaults \ + /usr/unsupported/lib/X11/app-defaults \ + /usr/athena/lib/X11/app-defaults \ + /usr/local/x11r5/lib/X11/app-defaults \ + /usr/lpp/Xamples/lib/X11/app-defaults \ + /lib/usr/lib/X11/app-defaults \ + \ + /usr/openwin/lib/app-defaults \ + /usr/openwin/lib/X11/app-defaults \ + /usr/openwin/share/lib/app-defaults \ + /usr/openwin/share/lib/X11/app-defaults \ + \ + /X11R6/lib/app-defaults \ + /X11R5/lib/app-defaults \ + /X11R4/lib/app-defaults \ + ; \ + do + if test -d "$ac_dir"; then + ac_x_app_defaults=$ac_dir + break + fi + done +]) + +AC_DEFUN(AC_PATH_X_APP_DEFAULTS, + [AC_REQUIRE_CPP() + AC_CACHE_CHECK([for X app-defaults directory], ac_cv_x_app_defaults, + [AC_PATH_X_APP_DEFAULTS_XMKMF + if test x"$ac_x_app_defaults" = x; then + AC_PATH_X_APP_DEFAULTS_DIRECT + fi + if test x"$ac_x_app_defaults" = x; then + ac_cv_x_app_defaults="/usr/lib/X11/app-defaults" + else + # Record where we found app-defaults for the cache. + ac_cv_x_app_defaults="$ac_x_app_defaults" + fi]) + eval ac_x_app_defaults="$ac_cv_x_app_defaults"]) + + +AC_DEFUN(AC_XPOINTER, + [AC_CACHE_CHECK([for XPointer], ac_cv_xpointer, + [AC_TRY_X_COMPILE([#include ], + [XPointer foo = (XPointer) 0;], + [ac_cv_xpointer=yes], + [ac_cv_xpointer=no])]) + if test "$ac_cv_xpointer" != yes; then + AC_DEFINE(XPointer,[char*]) + fi]) + + +# Random special-cases for X on certain pathological OSes. +# You know who you are. +# +AC_DEFUN(AC_X_RANDOM_PATHS, + [case "$host" in + *-hpux*) + + # The following arcana was gleaned from conversations with + # Eric Schwartz : + # + # On HPUX 10.x, the parts of X that HP considers "standard" live in + # /usr/{include,lib}/X11R6/. The parts that HP doesn't consider + # "standard", notably, Xaw and Xmu, live in /usr/contrib/X11R6/. + # Yet /usr/contrib/X11R6/ comes preinstalled on all HPUX systems. + # Also, there are symlinks from /usr/include/ and /usr/lib/ into + # /usr/{include,lib}/X11R6/, so that (if you don't use Xmu at all) + # you don't need any -I or -L arguments. + # + # On HPUX 9.x, /usr/{include,lib}/X11R5/ and /usr/contrib/X11R5/ + # are the same division as 10.x. However, there are no symlinks to + # the X stuff from /usr/include/ and /usr/lib/, so -I and -L + # arguments are always necessary. + # + # However, X11R6 was available on HPUX 9.x as a patch: if that + # patch was installed, then all of X11R6 went in to + # /usr/contrib/X11R6/ (there was no /usr/{include,lib}/X11R6/.) + # + # HPUX 8.x was the same as 9.x, but was X11R4 instead (I don't know + # whether R5 was available as a patch; R6 undoubtedly was not.) + # + # So. We try and use the highest numbered pair of + # /usr/{include,lib}/X11R?/ and /usr/contrib/X11R?/{include,lib}/ + # that are available. We do not mix and match different versions + # of X. + # + # Question I still don't know the answer to: (do you?) + # + # * On HPUX 9.x, where /usr/include/X11R5/ was standard, and + # /usr/contrib/X11R6/ could be installed as a patch, what was in + # that contrib directory? Did it contain so-called "standard" + # X11R6, or did it include Xaw and Xmu as well? If the former, + # where did one find Xaw and Xmu on 9.x R6 systems? Would this + # be a situation where one had to reach into the R5 headers and + # libs to find Xmu? That is, must both R6 and R5 directories + # be on the -I and -L lists in that case? + # + for version in X11R6 X11R5 X11R4 ; do + # if either pair of directories exists... + if test -d /usr/include/$version || test -d /usr/contrib/$version/include + then + # if contrib exists, use it... + if test -d /usr/contrib/$version/include ; then + X_CFLAGS="$X_CFLAGS -I/usr/contrib/$version/include" + X_LIBS="$X_LIBS -L/usr/contrib/$version/lib" + fi + # if the "standard" one exists, use it. + if test -d /usr/include/$version ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/$version" + X_LIBS="$X_LIBS -L/usr/lib/$version" + fi + # since at least one of the pair exists, go no farther. + break + fi + done + + # Now find Motif. Thanks for not making xmkmf find this by + # default, you losers. + # + if test -d /usr/include/Motif2.1 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif2.1" + X_LIBS="$X_LIBS -L/usr/lib/Motif2.1" + elif test -d /usr/include/Motif1.2 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.2" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.2" + elif test -d /usr/include/Motif1.1 ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/Motif1.1" + X_LIBS="$X_LIBS -L/usr/lib/Motif1.1" + fi + + # Now let's check for the pseudo-standard locations for OpenGL and XPM. + # + if test -d /opt/graphics/OpenGL/include ; then + # HP-UX 10.20 puts it here + X_CFLAGS="-I/opt/graphics/OpenGL/include $X_CFLAGS" + X_LIBS="-L/opt/graphics/OpenGL/lib $X_LIBS" + elif test -d /opt/Mesa/lib ; then + X_CFLAGS="-I/opt/Mesa/include $X_CFLAGS" + X_LIBS="-L/opt/Mesa/lib $X_LIBS" + fi + + + if test -d /opt/xpm/lib/X11 ; then + X_CFLAGS="-I/opt/xpm/include $X_CFLAGS" + X_LIBS="-L/opt/xpm/lib/X11 $X_LIBS" + fi + + # On HPUX, default to installing in /opt/xscreensaver/ instead of + # in /usr/local/, unless there is already an xscreensaver in + # /usr/local/bin/. This can be overridden with the --prefix arg + # to configure. I'm not sure this is the right thing to do, but + # Richard Lloyd says so... + # + if test \! -x /usr/local/bin/xscreensaver ; then + ac_default_prefix=/opt/xscreensaver + fi + + ;; + *-solaris*) + + # Thanks for not making xmkmf find this by default, pinheads. + # And thanks for moving things around again, too. Is this + # really the standard location now? What happened to the + # joke that this kind of thing went in /opt? + # cthomp says "answer: CDE (Common Disorganized Environment)" + # + if test -f /usr/dt/include/Xm/Xm.h ; then + X_CFLAGS="$X_CFLAGS -I/usr/dt/include" + MOTIF_LIBS="$MOTIF_LIBS -L/usr/dt/lib -R/usr/dt/lib" + + # Some versions of Slowlaris Motif require -lgen. But not all. Why? + AC_CHECK_LIB(gen, regcmp, [MOTIF_LIBS="$MOTIF_LIBS -lgen"]) + fi + + ;; + *-darwin*) + + # On MacOS X (10.x with "fink"), many things are under /sw/. + # + if test -d /sw/include ; then + X_CFLAGS="-I/sw/include $X_CFLAGS" + X_LIBS="-L/sw/lib $X_LIBS" + fi + ;; + esac]) + +AC_DEFUN(AC_CHECK_GETIFADDRS, + [AC_CACHE_CHECK([for getifaddrs], ac_cv_have_getifaddrs, + [AC_TRY_COMPILE([#include + #include + #include + #include ], + [struct ifaddrs *ifa; + getifaddrs (&ifa); + ifa->ifa_next = 0; + ifa->ifa_addr->sa_family = 0;], + [ac_cv_have_getifaddrs=yes], + [ac_cv_have_getifaddrs=no])]) + if test "$ac_cv_have_getifaddrs" = yes ; then + AC_DEFINE(HAVE_GETIFADDRS) + fi]) + + +############################################################################### +# +# Some utility functions to make checking for X things easier. +# +############################################################################### + +# Like AC_CHECK_HEADER, but it uses the already-computed -I directories. +# +AC_DEFUN(AC_CHECK_X_HEADER, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + AC_CHECK_HEADER([$1],[$2],[$3],[$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + +# Like AC_EGREP_HEADER, but it uses the already-computed -I directories. +# +AC_DEFUN(AC_EGREP_X_HEADER, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + AC_EGREP_HEADER([$1], [$2], [$3], [$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + +# Like AC_TRY_COMPILE, but it uses the already-computed -I directories. +# +AC_DEFUN(AC_TRY_X_COMPILE, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + AC_TRY_COMPILE([$1], [$2], [$3], [$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + + +# Like AC_CHECK_LIB, but it uses the already-computed -I and -L directories. +# Use this sparingly; it probably doesn't work very well on X programs. +# +AC_DEFUN(AC_CHECK_X_LIB, [ + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" +# ac_save_LIBS="$LIBS" + + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + # note: $X_CFLAGS includes $x_includes + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" + fi + # note: $X_LIBS includes $x_libraries + LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS" + + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + LDFLAGS=`eval eval eval eval eval eval eval eval eval echo $LDFLAGS` + AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5]) + CPPFLAGS="$ac_save_CPPFLAGS" + LDFLAGS="$ac_save_LDFLAGS" +# LIBS="$ac_save_LIBS" + ]) + +# Like AC_TRY_RUN, but it uses the already-computed -I directories. +# (But not the -L directories!) +# +AC_DEFUN(AC_TRY_X_RUN, [ + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + CPPFLAGS=`eval eval eval eval eval eval eval eval eval echo $CPPFLAGS` + AC_TRY_RUN([$1], [$2], [$3], [$4]) + CPPFLAGS="$ac_save_CPPFLAGS"]) + + + +# Usage: HANDLE_X_PATH_ARG([variable_name], +# [--command-line-option], +# [descriptive string]) +# +# All of the --with options take three forms: +# +# --with-foo (or --with-foo=yes) +# --without-foo (or --with-foo=no) +# --with-foo=/DIR +# +# This function, HANDLE_X_PATH_ARG, deals with the /DIR case. When it sees +# a directory (string beginning with a slash) it checks to see whether +# /DIR/include and /DIR/lib exist, and adds them to $X_CFLAGS and $X_LIBS +# as appropriate. +# +AC_DEFUN(HANDLE_X_PATH_ARG, [ + case "$[$1]" in + yes) ;; + no) ;; + + /*) + AC_MSG_CHECKING([for [$3] headers]) + d=$[$1]/include + if test -d $d; then + X_CFLAGS="-I$d $X_CFLAGS" + AC_MSG_RESULT($d) + else + AC_MSG_RESULT(not found ($d: no such directory)) + fi + + AC_MSG_CHECKING([for [$3] libs]) + d=$[$1]/lib + if test -d $d; then + X_LIBS="-L$d $X_LIBS" + AC_MSG_RESULT($d) + else + AC_MSG_RESULT(not found ($d: no such directory)) + fi + + # replace the directory string with "yes". + [$1]_req="yes" + [$1]=$[$1]_req + ;; + + *) + echo "" + echo "error: argument to [$2] must be \"yes\", \"no\", or a directory." + echo " If it is a directory, then \`DIR/include' will be added to" + echo " the -I list, and \`DIR/lib' will be added to the -L list." + exit 1 + ;; + esac + ]) + + + +############################################################################### +############################################################################### +# +# End of function definitions. Now start actually executing stuff. +# +############################################################################### +############################################################################### + +# WTF! autoconf emits this *way* too late. Do it earlier. +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + + +# random compiler setup +AC_CANONICAL_HOST +AC_PROG_CC_ANSI +AC_NO_LONG_STRING_WARNINGS +AC_NO_MISPLACED_DECLARATIONS +AC_NO_OBJECTIVE_C +AC_NO_CPLUSPLUS_COMMENTS_IN_C_CODE +AC_PROG_CPP +AC_C_CONST +AC_C_INLINE +AC_EXEEXT +AC_DEMAND_BC + +# stuff for Makefiles +AC_PROG_INSTALL +AC_PROG_INSTALL_DIRS +AC_PROG_MAKE_SET + +# By default, autoconf sets INSTALL_SCRIPT to '${INSTALL_PROGRAM}'. +# That's wrong: it should be set to '${INSTALL}', so that one can +# implement the "install-strip" target properly (strip executables, +# but do not try to strip scripts.) +# +INSTALL_SCRIPT='${INSTALL}' + +# random libc stuff +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) +AC_TYPE_MODE_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SIGNAL +AC_HEADER_TIME +AC_HEADER_SYS_WAIT +AC_HEADER_DIRENT +AC_GETTIMEOFDAY_ARGS +AC_SYS_LARGEFILE +AC_CHECK_FUNCS(select fcntl uname nice setpriority getcwd getwd putenv sbrk) +AC_CHECK_FUNCS(sigaction syslog realpath setrlimit) +AC_CHECK_FUNCS(setlocale) +AC_CHECK_ICMP +AC_CHECK_ICMPHDR +AC_CHECK_GETIFADDRS +AC_CHECK_HEADERS(crypt.h sys/select.h) +AC_PROG_PERL + +if test -z "$PERL" ; then + # don't let it be blank... + PERL=/usr/bin/perl +fi + +AC_PATH_XTRA + +if test "$have_x" != yes; then + AC_MSG_ERROR(Couldn't find X11 headers/libs. Try `$0 --help'.) +fi + +AC_PATH_X_APP_DEFAULTS +AC_X_RANDOM_PATHS +AC_XPOINTER + +AC_MSG_CHECKING(whether this is MacOS X) + ac_macosx=no + case "$host" in + *-apple-darwin* ) + ac_macosx=yes + ;; + esac +AC_MSG_RESULT($ac_macosx) + + +############################################################################### +# +# Gettext support +# +############################################################################### + +AC_PROG_INTLTOOL +GETTEXT_PACKAGE=xscreensaver +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", + [This is the name of the gettext package to use.]) +AC_DEFINE_UNQUOTED(PACKAGE, "$GETTEXT_PACKAGE", + [This is the same as GETTEXT_PACKAGE, but for the glade + generated code.]) +AC_SUBST(GETTEXT_PACKAGE) + +ALL_LINGUAS="ca da de es et fi fr hu it ja ko nb nl pl pt pt_BR ru sk sv vi wa zh_CN zh_TW" +AM_GLIB_GNU_GETTEXT +MKINSTALLDIRS="$INSTALL_DIRS" + + +############################################################################### +# +# Check for -lXmu (some fucked up vendors don't ship it...) +# +############################################################################### + +have_xmu=no +AC_CHECK_X_HEADER(X11/Xmu/Error.h, [have_xmu=yes],, + [#include + #include + #include ]) +if test "$have_xmu" = no ; then + XMU_SRCS='$(UTILS_SRC)/xmu.c' + XMU_OBJS='$(UTILS_BIN)/xmu.o' + XMU_LIBS='' +else + XMU_SRCS='' + XMU_OBJS='' + XMU_LIBS='-lXmu' + AC_DEFINE(HAVE_XMU) +fi + + +############################################################################### +# +# Check for the SunOS 4.1.x _get_wmShellWidgetClass bug. +# See comp.windows.x FAQ question 124. The right fix is to +# get OpenWindows 3.0 patches 100512-02 and 100573-03. +# +############################################################################### + +if test "$have_xmu" = yes ; then + case "$host" in + *-sunos4*) + AC_CACHE_CHECK([for the SunOS 4.1.x _get_wmShellWidgetClass bug], + ac_cv_sunos_xmu_bug, + [ac_save_LDFLAGS="$LDFLAGS" + if test \! -z "$x_libraries" ; then + LDFLAGS="$LDFLAGS -L$x_libraries" + fi + # Note: this trick never works! (Generally.) + # We're only getting away with using AC_TRY_LINK + # with X libraries because we know it's SunOS. + LDFLAGS="$LDFLAGS -lXmu -lXt -lX11 -lXext -lm" + AC_TRY_LINK(,, + [ac_cv_sunos_xmu_bug=no], + [ac_cv_sunos_xmu_bug=yes]) + LDFLAGS="$ac_save_LDFLAGS"]) + if test "$ac_cv_sunos_xmu_bug" = yes ; then + AC_CACHE_CHECK([whether the compiler understands -static], + ac_cv_ld_static, + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -static" + AC_TRY_LINK(,,[ac_cv_ld_static=yes],[ac_cv_ld_static=no]) + LDFLAGS="$ac_save_LDFLAGS"]) + if test "$ac_cv_ld_static" = yes ; then + LDFLAGS="$LDFLAGS -static" + else + LDFLAGS="$LDFLAGS -Bstatic" + fi + fi + ;; + esac +fi + + +############################################################################### +# +# Handle the --with-hackdir option +# +############################################################################### + +have_hackdir=yes +with_hackdir_req=unspecified +AC_ARG_WITH(hackdir,[ + +Installation options: + --with-hackdir=DIR Where to install the hundreds of demo executables. + Default: `PREFIX/libexec/xscreensaver/'], + [with_hackdir="$withval"; with_hackdir_req="$withval"],[with_hackdir=yes]) + +if test x"$with_hackdir" = xyes; then + HACKDIR='${libexecdir}/xscreensaver' +elif test x"$with_hackdir" = xno; then + HACKDIR='${bindir}' +else + HACKDIR=$with_hackdir +fi + +# canonicalize slashes. +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` + +# Expand HACKDIR as HACKDIR_FULL +HACKDIR_FULL=`eval eval eval eval eval eval eval eval eval echo $HACKDIR` + +# This option used to be called --enable-subdir; make sure that is no longer +# used, since configure brain-damagedly ignores unknown --enable options. + +obsolete_enable= +AC_ARG_ENABLE(subdir,,[obsolete_enable=yes]) +if test -n "$obsolete_enable"; then + echo "error: the --enable-subdir option has been replaced with" + echo " the new --with-hackdir option; see \`configure --help'" + echo " for more information." + exit 1 +fi + + +############################################################################### +# +# Handle the --with-configdir option +# Help for --with-x-app-defaults option added. +# +############################################################################### + +have_configdir=yes +with_configdir_req=unspecified +AC_ARG_WITH(configdir, +[ --with-configdir=DIR Where to install the data files that describe each + of the display modes to the GUI. + Default: `PREFIX/share/xscreensaver/config/' + --with-x-app-defaults=DIR + Where to install xscreensaver configuration file. +], + [with_configdir="$withval"; with_configdir_req="$withval"], + [with_configdir=yes]) + +if test x"$with_configdir" = xyes; then + HACK_CONF_DIR='${datadir}/xscreensaver/config' +elif test x"$with_configdir" = xno; then + echo "error: must be yes, or a pathname: --with-configdir=$with_configdir" + exit 1 +else + # there must be a better way than this... + if test -z "`echo $with_configdir | sed 's@^/.*@@'`" ; then + # absolute path + HACK_CONF_DIR=$with_configdir + else + # relative path + HACK_CONF_DIR="\${exec_prefix}$with_configdir" + fi +fi + + + + +############################################################################### +# +# Check for the SGI SCREEN_SAVER server extension. +# +############################################################################### + +#have_sgi=no +#with_sgi_req=unspecified +#AC_ARG_WITH(sgi-ext, +#[Except where noted, all of the --with options below can also take a +#directory argument: for example, `--with-motif=/opt/Motif'. That would +#cause /opt/Motif/include/ to be added to the -I list, and /opt/Motif/lib/ +#to be added to the -L list, assuming those directories exist. +# +#By default, support for each of these options will be built in, if the +#relevant library routines exist. At run time, they will then be used +#only if the X server being used supports them. Each --with option has +#a corresponding --without option, to override building support for them +#at all. +# +#Screen blanking and idle-detection options: +# +# --with-sgi-ext Include support for the SGI SCREEN_SAVER extension.], +# [with_sgi="$withval"; with_sgi_req="$withval"],[with_sgi=yes]) +# +#HANDLE_X_PATH_ARG(with_sgi, --with-sgi-ext, SGI SCREEN_SAVER) +# +#if test "$with_sgi" = yes; then +# AC_CHECK_X_HEADER(X11/extensions/XScreenSaver.h, +# [have_sgi=yes +# AC_DEFINE(HAVE_SGI_SAVER_EXTENSION)],, +# [#include ]) +# +#elif test "$with_sgi" != no; then +# echo "error: must be yes or no: --with-sgi-ext=$with_sgi" +# exit 1 +#fi + + +############################################################################### +# +# Check for the XIDLE server extension. +# +############################################################################### + +#have_xidle=no +#with_xidle_req=unspecified +#AC_ARG_WITH(xidle-ext, +#[ --with-xidle-ext Include support for the XIDLE extension.], +# [with_xidle="$withval"; with_xidle_req="$withval"],[with_xidle=yes]) +# +#HANDLE_X_PATH_ARG(with_xidle, --with-xidle-ext, XIDLE) +# +#if test "$with_xidle" = yes; then +# AC_CHECK_X_HEADER(X11/extensions/xidle.h, +# [have_xidle=yes +# AC_DEFINE(HAVE_XIDLE_EXTENSION)],, +# [#include ]) +#elif test "$with_xidle" != no; then +# echo "error: must be yes or no: --with-xidle-ext=$with_xidle" +# exit 1 +#fi + + +############################################################################### +# +# Check for the SGI-VIDEO-CONTROL server extension. +# +############################################################################### + +#have_sgivc=no +#with_sgivc_req=unspecified +#AC_ARG_WITH(sgivc-ext, +#[ --with-sgivc-ext Include support for the SGI-VIDEO-CONTROL extension.], +# [with_sgivc="$withval"; with_sgivc_req="$withval"],[with_sgivc=yes]) +# +#HANDLE_X_PATH_ARG(with_sgivc, --with-sgivc-ext, SGI-VIDEO-CONTROL) +# +#if test "$with_sgivc" = yes; then +# +# # first check for XSGIvc.h +# AC_CHECK_X_HEADER(X11/extensions/XSGIvc.h, [have_sgivc=yes],, +# [#include ]) +# +# # if that succeeded, then check for the -lXsgivc +# if test "$have_sgivc" = yes; then +# have_sgivc=no +# AC_CHECK_X_LIB(Xsgivc, XSGIvcQueryGammaMap, +# [have_sgivc=yes; SAVER_LIBS="$SAVER_LIBS -lXsgivc"], [true], +# -lXext -lX11) +# fi +# +# # if that succeeded, then we've really got it. +# if test "$have_sgivc" = yes; then +# AC_DEFINE(HAVE_SGI_VC_EXTENSION) +# fi +# +#elif test "$with_sgivc" != no; then +# echo "error: must be yes or no: --with-sgivc-ext=$with_sgivc" +# exit 1 +#fi + + +############################################################################### +# +# Check for the DPMS server extension. +# +############################################################################### + +have_dpms=no +with_dpms_req=unspecified +AC_ARG_WITH(dpms-ext, +[ --with-dpms-ext Include support for the DPMS extension.], + [with_dpms="$withval"; with_dpms_req="$withval"],[with_dpms=yes]) + +HANDLE_X_PATH_ARG(with_dpms, --with-dpms-ext, DPMS) + +if test "$with_dpms" = yes; then + + # first check for dpms.h + AC_CHECK_X_HEADER(X11/extensions/dpms.h, [have_dpms=yes],, + [#include + #include ]) + + # if that succeeded, then check for the DPMS code in the libraries + if test "$have_dpms" = yes; then + + # first look in -lXext (this is where it is with XFree86 4.0) + have_dpms=no + AC_CHECK_X_LIB(Xext, DPMSInfo, [have_dpms=yes], [true], -lXext -lX11) + + # if that failed, look in -lXdpms (this is where it was in XFree86 3.x) + if test "$have_dpms" = no; then + AC_CHECK_X_LIB(Xdpms, DPMSInfo, + [have_dpms=yes; XDPMS_LIBS="-lXdpms"], [true], + -lXext -lX11) + fi + fi + + + # if that succeeded, then we've really got it. + if test "$have_dpms" = yes; then + AC_DEFINE(HAVE_DPMS_EXTENSION) + fi + +elif test "$with_dpms" != no; then + echo "error: must be yes or no: --with-dpms-ext=$with_dpms" + exit 1 +fi + + +############################################################################### +# +# Check for the XINERAMA server extension. +# +############################################################################### + +have_xinerama=no +with_xinerama_req=unspecified +AC_ARG_WITH(xinerama-ext, +[ --with-xinerama-ext Include support for the XINERAMA extension.], + [with_xinerama="$withval"; with_xinerama_req="$withval"],[with_xinerama=yes]) + +HANDLE_X_PATH_ARG(with_xinerama, --with-xinerama-ext, XINERAMA) + +if test "$with_xinerama" = yes; then + + # first check for Xinerama.h + AC_CHECK_X_HEADER(X11/extensions/Xinerama.h, [have_xinerama=yes],, + [#include ]) + + # if that succeeded, then check for the XINERAMA code in the libraries + if test "$have_xinerama" = yes; then + + # first look in -lXext + have_xinerama=no + AC_CHECK_X_LIB(Xext, XineramaQueryScreens, [have_xinerama=yes], [true], + -lXext -lX11) + + # if that failed, look in -lXinerama (this is where it is in XFree86 4.1.) + if test "$have_xinerama" = no; then + AC_CHECK_X_LIB(Xinerama, XineramaQueryScreens, + [have_xinerama=yes; XINERAMA_LIBS="-lXinerama"], + [true], -lXext -lX11) + fi + fi + + # if that succeeded, then we've really got it. + if test "$have_xinerama" = yes; then + AC_DEFINE(HAVE_XINERAMA) + fi + +elif test "$with_xinerama" != no; then + echo "error: must be yes or no: --with-xinerama-ext=$with_xinerama" + exit 1 +fi + + +############################################################################### +# +# Check for the XINPUT server extension. +# +############################################################################### + +have_xinput=no +with_xinput_req=unspecified +AC_ARG_WITH(xinput-ext, +[ --with-xinput-ext Include support for the XInput extension.], + [with_xinput="$withval"; with_xinput_req="$withval"], [with_xinput=yes]) + +HANDLE_X_PATH_ARG(with_xinput, --with-xinput-ext, XINPUT) + +if test "$with_xinput" = yes; then + + # first check for Xinput.h + AC_CHECK_X_HEADER(X11/extensions/XInput.h, [have_xinput=yes],, + [#include ]) + + # if that succeeded, then check for libXi + if test "$have_xinput" = yes; then + have_xinput=no + AC_CHECK_X_LIB(Xi, XListInputDevices, + [have_xinput=yes; SAVER_LIBS="$SAVER_LIBS -lXi"], + [true], -lXext -lX11) + fi + + # if that succeeded, then we've really got it. + if test "$have_xinput" = yes; then + AC_DEFINE(HAVE_XINPUT) + fi + +elif test "$with_xinput" != no; then + echo "error: must be yes or no: --with-xinput-ext=$with_xinput" + exit 1 +fi + + +############################################################################### +# +# Check for the XF86VMODE server extension (for virtual screens.) +# +############################################################################### + +have_xf86vmode=no +with_xf86vmode_req=unspecified +AC_ARG_WITH(xf86vmode-ext, +[ --with-xf86vmode-ext Include support for XFree86 virtual screens.], + [with_xf86vmode="$withval"; with_xf86vmode_req="$withval"], + [with_xf86vmode=yes]) + +HANDLE_X_PATH_ARG(with_xf86vmode, --with-xf86vmode-ext, xf86vmode) + +VIDMODE_LIBS="" + +if test "$with_xf86vmode" = yes; then + + # first check for xf86vmode.h + AC_CHECK_X_HEADER(X11/extensions/xf86vmode.h, [have_xf86vmode=yes],, + [#include ]) + + # if that succeeded, then check for the -lXxf86vm + if test "$have_xf86vmode" = yes; then + have_xf86vmode=no + AC_CHECK_X_LIB(Xxf86vm, XF86VidModeGetViewPort, + [have_xf86vmode=yes; + VIDMODE_LIBS="-lXxf86vm"; + SAVER_LIBS="$SAVER_LIBS $VIDMODE_LIBS"], + [true], -lXext -lX11) + fi + + # if that succeeded, then we've really got it. + if test "$have_xf86vmode" = yes; then + AC_DEFINE(HAVE_XF86VMODE) + fi + +elif test "$with_xf86vmode" != no; then + echo "error: must be yes or no: --with-xf86vmode-ext=$with_xf86vmode" + exit 1 +fi + + +############################################################################### +# +# Check for the XF86VMODE server extension (for gamma fading.) +# +############################################################################### + +have_xf86gamma=no +have_xf86gamma_ramp=no +with_xf86gamma_req=unspecified +AC_ARG_WITH(xf86gamma-ext, +[ --with-xf86gamma-ext Include support for XFree86 gamma fading.], + [with_xf86gamma="$withval"; with_xf86gamma_req="$withval"], + [with_xf86gamma=yes]) + +HANDLE_X_PATH_ARG(with_xf86gamma, --with-xf86gamma-ext, xf86gamma) + +if test "$with_xf86gamma" = yes; then + + # first check for xf86vmode.h, if we haven't already + if test "$have_xf86vmode" = yes; then + have_xf86gamma=yes + else + AC_CHECK_X_HEADER(X11/extensions/xf86vmode.h, [have_xf86gamma=yes],, + [#include ]) + fi + + # if that succeeded, then check for the -lXxf86vm + if test "$have_xf86gamma" = yes; then + have_xf86gamma=no + AC_CHECK_X_LIB(Xxf86vm, XF86VidModeSetGamma, + [have_xf86gamma=yes], + [true], -lXext -lX11) + fi + + # check for the Ramp versions of the functions too. + if test "$have_xf86gamma" = yes; then + have_xf86gamma_ramp=no + AC_CHECK_X_LIB(Xxf86vm, XF86VidModeSetGammaRamp, + [have_xf86gamma_ramp=yes], + [true], -lXext -lX11) + fi + + # if those tests succeeded, then we've really got the functions. + if test "$have_xf86gamma" = yes; then + AC_DEFINE(HAVE_XF86VMODE_GAMMA) + fi + + if test "$have_xf86gamma_ramp" = yes; then + AC_DEFINE(HAVE_XF86VMODE_GAMMA_RAMP) + fi + + # pull in the lib, if we haven't already + if test "$have_xf86gamma" = yes -a "$have_xf86vmode" = no; then + SAVER_LIBS="$SAVER_LIBS -lXxf86vm" + fi + +elif test "$with_xf86gamma" != no; then + echo "error: must be yes or no: --with-xf86gamma-ext=$with_xf86vmode" + exit 1 +fi + + +############################################################################### +# +# Check for the RANDR (Resize and Rotate) server extension. +# +# We need this to detect when the resolution of the desktop +# has changed out from under us (this is a newer, different +# mechanism than the XF86VMODE virtual viewports.) +# +############################################################################### + +have_randr=no +with_randr_req=unspecified +AC_ARG_WITH(randr-ext, +[ --with-randr-ext Include support for the X Resize+Rotate extension.], + [with_randr="$withval"; with_randr_req="$withval"],[with_randr=yes]) + +HANDLE_X_PATH_ARG(with_randr, --with-randr-ext, RANDR) + +if test "$with_randr" = yes; then + + # first check for Xrandr.h + AC_CHECK_X_HEADER(X11/extensions/Xrandr.h, [have_randr=yes],, + [#include ]) + + # if that succeeded, then check for the XRR code in the libraries + if test "$have_randr" = yes; then + + # RANDR probably needs -lXrender + xrender_libs= + AC_CHECK_X_LIB(Xrender, XRenderSetSubpixelOrder, + [xrender_libs="-lXrender"], [true], -lXext -lX11) + + # first look for RANDR in -lXext + have_randr=no + AC_CHECK_X_LIB(Xext, XRRGetScreenInfo, + [have_randr=yes; SAVER_LIBS="$SAVER_LIBS $xrender_libs"], + [true], $xrender_libs -lXext -lX11) + + # if that failed, look in -lXrandr + if test "$have_randr" = no; then + AC_CHECK_X_LIB(Xrandr, XRRGetScreenInfo, + [have_randr=yes; SAVER_LIBS="$SAVER_LIBS -lXrandr $xrender_libs"], + [true], $xrender_libs -lXext -lX11) + fi + fi + + # if that succeeded, then we've really got it. + if test "$have_randr" = yes; then + AC_DEFINE(HAVE_RANDR) + + # Now check for version 1.2 in the same libs. + # Try to compile, since on MacOS 10.5.7, headers are older than libs! + AC_CACHE_CHECK([for XRRGetScreenResources], ac_cv_randr_12, + [ac_cv_randr_12=no + AC_TRY_X_COMPILE([#include + #include + #include ], + [XRRScreenResources *res = + XRRGetScreenResources (0, 0);], + [ac_cv_randr_12=yes], + [ac_cv_randr_12=no])]) + if test "$ac_cv_randr_12" = yes ; then + AC_DEFINE(HAVE_RANDR_12) + fi +# AC_CHECK_X_LIB(c, XRRGetOutputInfo, [AC_DEFINE(HAVE_RANDR_12)], +# [true], $SAVER_LIBS) + fi + + +elif test "$with_randr" != no; then + echo "error: must be yes or no: --with-randr-ext=$with_randr" + exit 1 +fi + + +############################################################################### +# +# Check for XF86MiscSetGrabKeysState (but only bother if we are already +# using other XF86 stuff.) +# +############################################################################### + +have_xf86miscsetgrabkeysstate=no +if test "$have_xf86gamma" = yes -o "$have_xf86vmode" = yes; then + AC_CHECK_X_LIB(Xxf86misc, XF86MiscSetGrabKeysState, + [have_xf86miscsetgrabkeysstate=yes], + [true], -lXext -lX11) + if test "$have_xf86miscsetgrabkeysstate" = yes ; then + SAVER_LIBS="$SAVER_LIBS -lXxf86misc" + AC_DEFINE(HAVE_XF86MISCSETGRABKEYSSTATE) + fi +fi + + +############################################################################### +# +# Check for HP XHPDisableReset and XHPEnableReset. +# +############################################################################### + +AC_MSG_CHECKING([for XHPDisableReset in X11/XHPlib.h]) +AC_EGREP_X_HEADER(XHPDisableReset, X11/XHPlib.h, + [AC_DEFINE(HAVE_XHPDISABLERESET) + SAVER_LIBS="-lXhp11 $SAVER_LIBS" + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)]) + + +############################################################################### +# +# Check for /proc/interrupts. +# +############################################################################### + +have_proc_interrupts=no +with_proc_interrupts_req=unspecified +AC_ARG_WITH(proc-interrupts, +[ --with-proc-interrupts Include support for consulting the /proc/interrupts + file to notice keyboard activity.], + [with_proc_interrupts="$withval"; with_proc_interrupts_req="$withval"], + [with_proc_interrupts=yes]) + +if test "$with_proc_interrupts" = yes; then + + # Note that we may be building in an environment (e.g. Debian buildd chroot) + # without a proper /proc filesystem. If /proc/interrupts exists, then we'll + # check that it has the bits we need, but otherwise we'll just go on faith. + # + have_proc_interrupts=yes + + if test -f /proc/interrupts; then + AC_CACHE_CHECK([whether /proc/interrupts contains keyboard data], + ac_cv_have_proc_interrupts, + [ac_cv_have_proc_interrupts=no + if grep 'keyboard\|i8042' /proc/interrupts >/dev/null 2>&1 ; then + ac_cv_have_proc_interrupts=yes + fi + ]) + have_proc_interrupts=$ac_cv_have_proc_interrupts + fi + + if test "$have_proc_interrupts" = yes; then + AC_DEFINE(HAVE_PROC_INTERRUPTS) + fi + +elif test "$with_proc_interrupts" != no; then + echo "error: must be yes or no: --with-proc-interrupts=$with_proc_interrupts" + exit 1 +fi + + +############################################################################### +# +# The --enable-locking option +# +############################################################################### + +AC_ARG_ENABLE(locking,[Screen locking options: + --enable-locking Compile in support for locking the display. + --disable-locking Do not allow locking at all.], + [enable_locking="$enableval"], + [if test "$ac_macosx" = yes; then + # We can't lock on MacOS X, so default to not compiling in support for it. + # But allow --enable-locking to override that, so I can debug Linux locking + # under MacOS X11. + enable_locking=no + else + enable_locking=yes + fi]) +if test "$enable_locking" = yes; then + true +elif test "$enable_locking" = no; then + AC_DEFINE(NO_LOCKING) +else + echo "error: must be yes or no: --enable-locking=$enable_locking" + exit 1 +fi + + +############################################################################### +# +# Whether to allow root password to unblank. +# +############################################################################### +AC_ARG_ENABLE(root-passwd, [ + --enable-root-passwd Allow root passwd to unlock screen. + --disable-root-passwd Do not allow that.], + [enable_root_passwd="$enableval"],[enable_root_passwd=yes]) +if test "$enable_root_passwd" = yes; then + AC_DEFINE(ALLOW_ROOT_PASSWD) + true +elif test "$enable_root_passwd" != no; then + echo "error: must be yes or no: --enable-root-passwd=$enable_root_passwd" + exit 1 +fi + +############################################################################### +# +# Check for PAM. +# +############################################################################### + +case "$host" in + *-solaris*) + # Solaris systems tend to come with PAM misconfigured. + # Don't build it by default, even if the headers exist. + with_pam_default=no + ;; + *) + # Default to building PAM support on all other systems, if it exists. + with_pam_default=yes + ;; +esac + +have_pam=no +with_pam_req=unspecified + +AC_ARG_WITH(pam, +[ --with-pam Include support for PAM (Pluggable Auth Modules.)], + [with_pam="$withval"; with_pam_req="$withval"],[with_pam=$with_pam_default]) + +AC_ARG_WITH([pam_service_name], + AC_HELP_STRING([--with-pam-service-name], + [NAME arg is the name of the PAM service that + xscreensaver will authenticate as.]), + [pam_service_name="$withval"],[pam_service_name="xscreensaver"]) + +AC_ARG_ENABLE(pam-check-account-type, + [AC_HELP_STRING([--enable-pam-check-account-type], + [Whether PAM should check the result of account + modules when authenticating. Only do this if you + have account configured properly on your system.])], + [enable_pam_check_account_type="$enableval"],[enable_pam_check_account_type=no]) +if test "$enable_pam_check_account_type" = yes ; then + AC_DEFINE(PAM_CHECK_ACCOUNT_TYPE) + true +elif test "$enable_pam_check_account_type" != no ; then + echo "error: must be yes or no: --enable-pam-check-account-type=$enable_pam_check_account_type" + exit 1 +fi + +HANDLE_X_PATH_ARG(with_pam, --with-pam, PAM) + +if test "$enable_locking" = yes -a "$with_pam" = yes; then + AC_CACHE_CHECK([for PAM], ac_cv_pam, + [AC_TRY_X_COMPILE([#include ],, + [ac_cv_pam=yes], + [ac_cv_pam=no])]) + if test "$ac_cv_pam" = yes ; then + have_pam=yes + AC_DEFINE(HAVE_PAM) + AC_DEFINE_UNQUOTED(PAM_SERVICE_NAME,"$pam_service_name") + + PASSWD_LIBS="${PASSWD_LIBS} -lpam" + + # libpam typically requires dlopen and dlsym. On FreeBSD, + # those are in libc. On Linux and Solaris, they're in libdl. + AC_CHECK_LIB(dl, dlopen, [PASSWD_LIBS="${PASSWD_LIBS} -ldl"]) + + # On Linux, sigtimedwait() is in libc; on Solaris, it's in librt. + have_timedwait=no + AC_CHECK_LIB(c, sigtimedwait, + [have_timedwait=yes + AC_DEFINE(HAVE_SIGTIMEDWAIT)]) + if test "$have_timedwait" = no ; then + AC_CHECK_LIB(rt, sigtimedwait, [have_timedwait=yes + AC_DEFINE(HAVE_SIGTIMEDWAIT) + PASSWD_LIBS="${PASSWD_LIBS} -lrt"]) + fi + + AC_MSG_CHECKING(how to call pam_strerror) + AC_CACHE_VAL(ac_cv_pam_strerror_args, + [AC_TRY_X_COMPILE([#include + #include + #include ], + [pam_handle_t *pamh = 0; + char *s = pam_strerror(pamh, PAM_SUCCESS);], + [ac_pam_strerror_args=2], + [AC_TRY_X_COMPILE([#include + #include + #include ], + [char *s = + pam_strerror(PAM_SUCCESS);], + [ac_pam_strerror_args=1], + [ac_pam_strerror_args=0])]) + ac_cv_pam_strerror_args=$ac_pam_strerror_args]) + ac_pam_strerror_args=$ac_cv_pam_strerror_args + if test "$ac_pam_strerror_args" = 1 ; then + AC_MSG_RESULT(one argument) + elif test "$ac_pam_strerror_args" = 2 ; then + AC_DEFINE(PAM_STRERROR_TWO_ARGS) + AC_MSG_RESULT(two arguments) + else + AC_MSG_RESULT(unknown) + fi + +# Check pam_fail_delay + AC_MSG_CHECKING(pam_fail_delay in -lpam) + AC_CACHE_VAL(ac_cv_pam_fail_delay, + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="-lpam" + AC_TRY_LINK([#include ], + [pam_handle_t *pamh = 0; + unsigned int usec = 1; + int status = pam_fail_delay (pamh, usec);], + [ac_pam_fail_delay=yes], + [ac_pam_fail_delay=no]) + ac_cv_pam_fail_delay=$ac_pam_fail_delay, + LDFLAGS=$ac_save_LDFLAGS]) + + if test "$ac_pam_fail_delay" = yes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PAM_FAIL_DELAY) + else + AC_MSG_RESULT(no) + fi + + fi +fi + + +############################################################################### +# +# Check for Kerberos. +# +############################################################################### + +have_kerberos=no +have_kerberos5=no +with_kerberos_req=unspecified + +AC_ARG_WITH(kerberos, +[ --with-kerberos Include support for Kerberos authentication.], + [with_kerberos="$withval"; with_kerberos_req="$withval"],[with_kerberos=yes]) + +HANDLE_X_PATH_ARG(with_kerberos, --with-kerberos, Kerberos) + +if test "$enable_locking" = yes -a "$with_kerberos" = yes; then + AC_CACHE_CHECK([for Kerberos 4], ac_cv_kerberos, + [AC_TRY_X_COMPILE([#include ],, + [ac_cv_kerberos=yes], + [ac_cv_kerberos=no])]) + AC_CACHE_CHECK([for Kerberos 5], ac_cv_kerberos5, + [AC_TRY_X_COMPILE([#include ],, + [ac_cv_kerberos5=yes], + [ac_cv_kerberos5=no])]) + + if test "$ac_cv_kerberos" = yes ; then + have_kerberos=yes + AC_DEFINE(HAVE_KERBEROS) + fi + + if test "$ac_cv_kerberos5" = yes ; then + + # Andrew Snare wrote: + # + # You were assuming that if kerberosV (krb5) was found, then kerberosIV + # (krb4) was also available. This turns out not to be the case with + # mit-krb-1.2.7; apparently backwards-compatibility with KerberosIV + # is optional. + # + # So, disable kerberosV support if libkrb4 can't be found. + # This is not the best solution, but it makes the compile not fail. + # + AC_CHECK_X_LIB(krb4, krb_get_tf_realm, + [have_kerberos=yes], + [have_kerberos=no]) + if test "$have_kerberos" = yes ; then + have_kerberos5=yes + AC_DEFINE(HAVE_KERBEROS) + AC_DEFINE(HAVE_KERBEROS5) + else + have_kerberos5=no + AC_MSG_WARN([Cannot find compat lib (libkrb4) needed to use Kerberos 5]) + fi + + fi + + if test "$have_kerberos5" = yes ; then + # from Matt Knopp + # (who got it from amu@mit.edu) + + PASSWD_LIBS="$PASSWD_LIBS -lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err" + + # jwz: MacOS X uses -lkrb5, but not -lcrypt + AC_CHECK_X_LIB(crypt, crypt, [PASSWD_LIBS="$PASSWD_LIBS -lcrypt"]) + + elif test "$have_kerberos" = yes ; then + # from Tim Showalter for FreeBSD 4.2 + PASSWD_LIBS="$PASSWD_LIBS -lkrb -ldes -lcom_err" + fi + + if test "$have_kerberos" = yes ; then + AC_CHECK_FUNC(res_search,, + AC_CHECK_LIB(resolv,res_search,PASSWD_LIBS="${PASSWD_LIBS} -lresolv", + AC_MSG_WARN([Can't find DNS resolver libraries needed for Kerberos]) + )) + fi +fi + + +############################################################################### +# +# Check for the nine billion variants of shadow passwords... +# +############################################################################### + +need_setuid=no + +have_shadow=no +with_shadow_req=unspecified + +AC_ARG_WITH(shadow, +[ --with-shadow Include support for shadow password authentication.], + [with_shadow="$withval"; with_shadow_req="$withval"],[with_shadow=yes]) + +HANDLE_X_PATH_ARG(with_shadow, --with-shadow, shadow password) + +if test "$enable_locking" = no ; then + with_shadow_req=no + with_shadow=no +fi + + +############################################################################### +# +# Check for Sun "adjunct" passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for Sun-style shadow passwords], ac_cv_sun_adjunct, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include + #include ], + [struct passwd_adjunct *p = getpwanam("nobody"); + const char *pw = p->pwa_passwd;], + [ac_cv_sun_adjunct=yes], + [ac_cv_sun_adjunct=no])]) + if test "$ac_cv_sun_adjunct" = yes; then + have_shadow_adjunct=yes + have_shadow=yes + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for DEC and SCO so-called "enhanced" security. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for DEC-style shadow passwords], ac_cv_enhanced_passwd, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include + #include ], + [struct pr_passwd *p; + const char *pw; + set_auth_parameters(0, 0); + check_auth_parameters(); + p = getprpwnam("nobody"); + pw = p->ufld.fd_encrypt;], + [ac_cv_enhanced_passwd=yes], + [ac_cv_enhanced_passwd=no])]) + if test $ac_cv_enhanced_passwd = yes; then + have_shadow_enhanced=yes + have_shadow=yes + need_setuid=yes + + # On SCO, getprpwnam() is in -lprot (which uses nap() from -lx) + # (I'm told it needs -lcurses too, but I don't understand why.) + # But on DEC, it's in -lsecurity. + # + AC_CHECK_LIB(prot, getprpwnam, + [PASSWD_LIBS="$PASSWD_LIBS -lprot -lcurses -lx"], + [AC_CHECK_LIB(security, getprpwnam, + [PASSWD_LIBS="$PASSWD_LIBS -lsecurity"])], + [-lx]) + fi +fi + +############################################################################### +# +# Check for HP's entry in the "Not Invented Here" Sweepstakes. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for HP-style shadow passwords], ac_cv_hpux_passwd, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include + #include ], + [struct s_passwd *p = getspwnam("nobody"); + const char *pw = p->pw_passwd;], + [ac_cv_hpux_passwd=yes], + [ac_cv_hpux_passwd=no])]) + if test "$ac_cv_hpux_passwd" = yes; then + have_shadow_hpux=yes + have_shadow=yes + need_setuid=yes + + # on HPUX, bigcrypt is in -lsec + AC_CHECK_LIB(sec, bigcrypt, [PASSWD_LIBS="$PASSWD_LIBS -lsec"]) + fi +fi + + +############################################################################### +# +# Check for FreeBSD-style shadow passwords. +# +# On FreeBSD, getpwnam() and friends work just like on non-shadow- +# password systems -- except you only get stuff in the pw_passwd field +# if the running program is setuid. So, guess that we've got this +# lossage to contend with if /etc/master.passwd exists, and default to +# a setuid installation. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for FreeBSD-style shadow passwords], ac_cv_master_passwd, + [if test -f /etc/master.passwd ; then + ac_cv_master_passwd=yes + else + ac_cv_master_passwd=no + fi]) + if test "$ac_cv_master_passwd" = yes; then + need_setuid=yes + fi +fi + + +############################################################################### +# +# Check for traditional (ha!) shadow passwords. +# +############################################################################### + +if test "$with_shadow" = yes ; then + AC_CACHE_CHECK([for generic shadow passwords], ac_cv_shadow, + [AC_TRY_X_COMPILE([#include + #include + #include + #include + #include ], + [struct spwd *p = getspnam("nobody"); + const char *pw = p->sp_pwdp;], + [ac_cv_shadow=yes], + [ac_cv_shadow=no])]) + if test "$ac_cv_shadow" = yes; then + have_shadow=yes + need_setuid=yes + + # On some systems (UnixWare 2.1), getspnam() is in -lgen instead of -lc. + have_getspnam=no + AC_CHECK_LIB(c, getspnam, [have_getspnam=yes]) + if test "$have_getspnam" = no ; then + AC_CHECK_LIB(gen, getspnam, + [have_getspnam=yes; PASSWD_LIBS="$PASSWD_LIBS -lgen"]) + fi + fi +fi + + +############################################################################### +# +# Check for other libraries needed for non-shadow passwords. +# +############################################################################### + +if test "$enable_locking" = yes ; then + + # On some systems (UnixWare 2.1), crypt() is in -lcrypt instead of -lc. + have_crypt=no + AC_CHECK_LIB(c, crypt, [have_crypt=yes]) + if test "$have_crypt" = no ; then + AC_CHECK_LIB(crypt, crypt, + [have_crypt=yes; PASSWD_LIBS="$PASSWD_LIBS -lcrypt"]) + fi +fi + + +# Most of the above shadow mechanisms will have set need_setuid to yes, +# if they were found. But, on some systems, we need setuid even when +# using plain old vanilla passwords. +# +if test "$enable_locking" = yes ; then + case "$host" in + *-hpux* | *-aix* | *-netbsd* | *-freebsd* | *-openbsd* ) + need_setuid=yes + ;; + esac +fi + + +if test "$have_shadow_adjunct" = yes ; then + AC_DEFINE(HAVE_ADJUNCT_PASSWD) +elif test "$have_shadow_enhanced" = yes ; then + AC_DEFINE(HAVE_ENHANCED_PASSWD) +elif test "$have_shadow_hpux" = yes ; then + AC_DEFINE(HAVE_HPUX_PASSWD) +elif test "$have_shadow" = yes ; then + AC_DEFINE(HAVE_SHADOW_PASSWD) +fi + + +############################################################################### +# +# Check for external password helper +# On SuSE, instead of having xscreensaver be a setuid program, they +# fork an external program that takes the password on stdin, and +# returns true if that password is a valid one. Then only that +# smaller program needs to be setuid. +# +# (Note that this external program is not a GUI: the GUI is still +# all in xscreensaver itself; the external program just does auth.) +# +############################################################################### + +have_passwd_helper=no +with_passwd_helper_req=unspecified + +AC_ARG_WITH(passwd-helper, +[ --with-passwd-helper Include support for an external password + verification helper program.], + [with_passwd_helper="$withval"; with_passwd_helper_req="$withval"],[with_passwd_helper=no]) +# no HANDLE_X_PATH_ARG for this one + +if test "$enable_locking" = no ; then + with_passwd_helper_req=no + with_passwd_helper=no +fi + +case "$with_passwd_helper" in + ""|no) : ;; + /*) + AC_DEFINE_UNQUOTED(PASSWD_HELPER_PROGRAM, "$with_passwd_helper") + have_passwd_helper=yes;; + *) + echo "error: --with-passwd-helper needs full pathname of helper (not '$with_passwd_helper')." >&2 + exit 1 +esac + + +############################################################################### +# +# Check for a login manager for a "New Login" button on the lock dialog. +# Usually this will be "/usr/bin/gdmflexiserver". +# +############################################################################### + +with_login_manager_req=unspecified +default_login_manager_1='gdmflexiserver -ls' +default_login_manager_2='kdmctl reserve' + +AC_ARG_WITH(login-manager, +[ --with-login-manager Put a "New Login" button on the unlock dialog that + runs a login manager like gdmflexiserver or kdmctl.], + [with_login_manager="$withval"; with_login_manager_req="$withval"], + [with_login_manager=yes]) +# no HANDLE_X_PATH_ARG for this one + +if test "$enable_locking" = no ; then + with_login_manager_req=no + with_login_manager=no +fi + +case "$with_login_manager_req" in + no) + with_login_manager="" + ;; + + yes|unspecified) + # Try both defaults, use the one that exists. + + set dummy $default_login_manager_1 ; login_manager_tmp=$2 + unset ac_cv_path_login_manager_tmp # don't cache + AC_PATH_PROG(login_manager_tmp, $login_manager_tmp, []) + if test ! -z "$login_manager_tmp" ; then + with_login_manager="$default_login_manager_1" + else + set dummy $default_login_manager_2 ; login_manager_tmp=$2 + unset ac_cv_path_login_manager_tmp # don't cache + AC_PATH_PROG(login_manager_tmp, $login_manager_tmp, []) + if test ! -z "$login_manager_tmp" ; then + with_login_manager="$default_login_manager_2" + else + with_login_manager="" + fi + fi + ;; + + /*) + # absolute path specified on cmd line + set dummy $with_login_manager_req ; login_manager_tmp=$2 + AC_MSG_CHECKING([for $login_manager_tmp]) + if test -x "$login_manager_tmp" ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + with_login_manager="" + fi + ;; + + *) + # relative path specified on cmd line + set dummy $with_login_manager_req ; login_manager_tmp=$2 + unset ac_cv_path_login_manager_tmp # don't cache + AC_PATH_PROG(login_manager_tmp, $login_manager_tmp, []) + if test -z "$login_manager_tmp" ; then + with_login_manager="" + else + with_login_manager="$login_manager_tmp" + fi + ;; +esac +ac_cv_login_manager_program="$with_login_manager" + +NEW_LOGIN_COMMAND_P='' +NEW_LOGIN_COMMAND="$ac_cv_login_manager_program" + +AC_MSG_CHECKING(for login manager) +if test -z "$NEW_LOGIN_COMMAND" ; then + NEW_LOGIN_COMMAND="$default_login_manager_1" + NEW_LOGIN_COMMAND_P='! ' + AC_MSG_RESULT($NEW_LOGIN_COMMAND (disabled)) +else + AC_MSG_RESULT($NEW_LOGIN_COMMAND) +fi + + +############################################################################### +# +# Check for -lgtk (and Gnome stuff) +# +############################################################################### + +have_gtk=no +with_gtk_req=unspecified +AC_ARG_WITH(gtk,[ +User interface options: + + --with-gtk Use the Gtk toolkit for the user interface.], + [with_gtk="$withval"; with_gtk_req="$withval"],[with_gtk=yes]) + +# if --with-gtk=/directory/ was specified, remember that directory so that +# we can also look for the `gtk-config' program in that directory. +case "$with_gtk" in + /*) + gtk_dir="$with_gtk" + ;; + *) + gtk_dir="" + ;; +esac + +HANDLE_X_PATH_ARG(with_gtk, --with-gtk, Gtk) + +if test "$with_gtk" != yes -a "$with_gtk" != no ; then + echo "error: must be yes or no: --with-gtk=$with_gtk" + exit 1 +fi + + +parse_gtk_version_string() { + # M4 sucks!! + changequote(X,Y) + maj=`echo $ac_gtk_version_string | sed -n 's/\..*//p'` + min=`echo $ac_gtk_version_string | sed -n 's/[^.]*\.\([^.]*\).*/\1/p'` + changequote([,]) + ac_gtk_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_gtk_version"; then + ac_gtk_version=unknown + ac_gtk_version_string=unknown + fi +} + +# Find pkg-config... (need this for both gtk and gdk_pixbuf.) +# if the user specified --with-gtk=/foo/ then look there. +# +gtk_path="$PATH" +if test ! -z "$gtk_dir"; then + # canonicalize slashes. + foo=`echo "${gtk_dir}/bin" | sed 's@//*@/@g'` + gtk_path="$foo:$gtk_path" +fi + +AC_PATH_PROGS(pkg_config, pkg-config,, $gtk_path) + +if test -z "$pkg_config" ; then + AC_MSG_WARN([pkg-config not found!]) + pkg_config="false" +fi + + +# Utility function for running pkg-config-based tests... +# +pkgs='' +pkg_check_version() { + if test "$ok" = yes ; then + req="$1" + min="$2" + AC_MSG_CHECKING(for $req) + if $pkg_config --exists "$req" ; then + vers=`$pkg_config --modversion "$req"` + if $pkg_config --exists "$req >= $min" ; then + AC_MSG_RESULT($vers) + pkgs="$pkgs $req" + return 1 + else + AC_MSG_RESULT($vers (wanted >= $min)) + ok=no + return 0 + fi + else + AC_MSG_RESULT(no) + ok=no + return 0 + fi + fi +} + + +jurassic_gtk=no +gtk_halfassed=no + +if test "$with_gtk" = yes; then + have_gtk=no + + ok="yes" + pkg_check_version gtk+-2.0 2.0.1 ; ac_gtk_version_string="$vers" + pkg_check_version gmodule-2.0 2.0.0 + pkg_check_version libxml-2.0 2.4.6 + pkg_check_version libglade-2.0 1.99.0 + pkg_check_version gdk-pixbuf-2.0 2.0.0 + pkg_check_version gdk-pixbuf-xlib-2.0 2.0.0 + have_gtk="$ok" + + if test "$have_gtk" = no; then + if test -n "$ac_gtk_version_string" ; then + gtk_halfassed="$ac_gtk_version_string" + gtk_halfassed_lib="$req" + fi + fi + + if test "$have_gtk" = yes; then + parse_gtk_version_string + jurassic_gtk=no + fi + + if test "$have_gtk" = yes; then + AC_CACHE_CHECK([for Gtk includes], ac_cv_gtk_config_cflags, + [ac_cv_gtk_config_cflags=`$pkg_config --cflags $pkgs`]) + AC_CACHE_CHECK([for Gtk libs], ac_cv_gtk_config_libs, + [ac_cv_gtk_config_libs=`$pkg_config --libs $pkgs`]) + fi + + ac_gtk_config_cflags=$ac_cv_gtk_config_cflags + ac_gtk_config_libs=$ac_cv_gtk_config_libs + + GTK_EXTRA_OBJS="" + GTK_DATADIR="" + if test "$have_gtk" = yes; then + GTK_DATADIR=`$pkg_config --variable=prefix gtk+-2.0` + GTK_DATADIR="$GTK_DATADIR/share" + fi + + if test "$have_gtk" = yes; then + INCLUDES="$INCLUDES $ac_gtk_config_cflags" + GTK_LIBS="$GTK_LIBS $ac_gtk_config_libs" + AC_DEFINE(HAVE_GTK) + AC_DEFINE(HAVE_GTK2) + AC_DEFINE(HAVE_XML) + fi + +fi + + +# Check for the various Gnome help and URL loading programs. +# +WITH_BROWSER=gnome-open +if test "$have_gtk" = yes; then + AC_CHECK_PROGS(gnome_open_program, gnome-open) + AC_CHECK_PROGS(gnome_url_show_program, gnome-url-show) +fi + + +############################################################################### +# +# Check for -lXm. +# +############################################################################### + +have_motif=no +with_motif_req=unspecified +AC_ARG_WITH(motif,[ --with-motif Use the Motif toolkit for the user interface + (no longer supported.)], + [with_motif="$withval"; with_motif_req="$withval"],[with_motif=no]) + +HANDLE_X_PATH_ARG(with_motif, --with-motif, Motif) + +if test "$with_motif" != yes -a "$with_motif" != no ; then + echo "error: must be yes or no: --with-motif=$with_motif" + exit 1 +fi + +if test "$with_motif" = yes; then + have_motif=no + AC_CHECK_X_HEADER(Xm/Xm.h, + [have_motif=yes + AC_DEFINE(HAVE_MOTIF) + MOTIF_LIBS="$MOTIF_LIBS -lXm"],, + [#include + #include + #include ]) +fi + + +if test "$have_motif" = yes; then + AC_CHECK_X_HEADER(Xm/ComboBox.h, [AC_DEFINE(HAVE_XMCOMBOBOX)],, + [#include + #include + #include ]) +fi + + +############################################################################### +# +# Checking whether Motif is really Lesstif. +# +############################################################################### + +have_lesstif=no +if test "$have_motif" = yes ; then + AC_CACHE_CHECK([whether Motif is really LessTif], + ac_cv_have_lesstif, + [AC_TRY_X_COMPILE([#include ], + [long vers = LesstifVersion;], + [ac_cv_have_lesstif=yes], + [ac_cv_have_lesstif=no])]) + have_lesstif=$ac_cv_have_lesstif +fi + + +lesstif_version=unknown +lesstif_version_string=unknown + +if test "$have_lesstif" = yes ; then + ltv=unknown + echo unknown > conftest-lt + AC_CACHE_CHECK([LessTif version number], + ac_cv_lesstif_version_string, + [AC_TRY_X_RUN([#include + #include + int main() { + FILE *f = fopen("conftest-lt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", LesstifVersion, + LESSTIF_VERSION, LESSTIF_REVISION); + fclose(f); + exit(0); + }], + [ltv=`cat conftest-lt` + ac_cv_lesstif_version=`echo $ltv | sed 's/ .*//'` + ac_cv_lesstif_version_string=`echo $ltv | sed 's/.* //'`], + [ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown], + [ac_cv_lesstif_version=unknown + ac_cv_lesstif_version_string=unknown])]) + rm -f conftest-lt + lesstif_version=$ac_cv_lesstif_version + lesstif_version_string=$ac_cv_lesstif_version_string + +fi + + +if test "$have_motif" = yes ; then + mtv=unknown + echo unknown > conftest-mt + AC_CACHE_CHECK([Motif version number], + ac_cv_motif_version_string, + [AC_TRY_X_RUN([#include + #include + int main() { + FILE *f = fopen("conftest-mt", "w"); + if (!f) exit(1); + fprintf(f, "%d %d.%d\n", XmVersion, + XmVERSION, XmREVISION); + fclose(f); + exit(0); + }], + [mtv=`cat conftest-mt` + ac_cv_motif_version=`echo $mtv | sed 's/ .*//'` + ac_cv_motif_version_string=`echo $mtv | sed 's/.* //'`], + [ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown], + [ac_cv_motif_version=unknown + ac_cv_motif_version_string=unknown])]) + rm -f conftest-mt + motif_version=$ac_cv_motif_version + motif_version_string=$ac_cv_motif_version_string + +fi + + +############################################################################### +# +# Checking whether Motif requires -lXpm. +# +# If this is Motif 2.x, and we have XPM, then link against XPM as well. +# The deal is, Motif 2.x requires XPM -- but it's a compilation option +# of the library whether to build the XPM code into libXm, or whether +# to rely on an external libXm. So the only way to tell whether XPM is +# a link-time requirement is to examine libXm.a, which is very +# difficult to do in an autoconf script. So... if it's Motif 2.x, we +# always link against XPM if the XPM lib exists (and this will be a +# no-op if libXm happens to already have the XPM code in it.) +# +############################################################################### + +motif_requires_xpm=no +if test "$have_motif" = yes ; then + AC_MSG_CHECKING(whether Motif requires XPM) + if test "$motif_version" = "unknown" || test "$motif_version" -ge 2000 + then + motif_requires_xpm=yes + AC_MSG_RESULT(maybe) + else + AC_MSG_RESULT(no) + fi +fi + + +############################################################################### +# +# Checking whether Motif requires -lXp. +# +# Some versions of Motif (2.1.0, at least) require -lXp, the "X Printing +# Extension". Why this extension isn't in -lXext with all the others, +# I have no idea. +# +############################################################################### + +have_xp_ext=no +if test "$have_motif" = yes ; then + have_xp_ext=no + AC_CHECK_X_LIB(Xp, XpQueryExtension, + [have_xp_ext=yes; MOTIF_LIBS="$MOTIF_LIBS -lXp"], + [true], -lX11 -lXext -lm) +fi + + +############################################################################### +# +# Checking whether Motif requires -lXintl (for _Xsetlocale.) +# +############################################################################### + +have_xintl=no +if test "$have_motif" = yes ; then + AC_CHECK_X_LIB(Xintl, _Xsetlocale, [have_xintl=yes], [have_xintl=no], + -lX11 -lXext -lm) + if test "$have_xintl" = yes; then + MOTIF_LIBS="$MOTIF_LIBS -lXintl" + fi +fi + + +############################################################################### +# +# Check for -lGL or -lMesaGL. +# +############################################################################### + +have_gl=no +ac_have_mesa_gl=no +with_gl_req=unspecified +gl_halfassed=no +AC_ARG_WITH(gl,[ +Graphics options: + + --with-gl Build those demos which depend on OpenGL.], + [with_gl="$withval"; with_gl_req="$withval"],[with_gl=yes]) + +HANDLE_X_PATH_ARG(with_gl, --with-gl, GL) + +ac_mesagl_version=unknown +ac_mesagl_version_string=unknown + +if test "$with_gl" = yes; then + AC_CHECK_X_HEADER(GL/gl.h, have_gl=yes, have_gl=no) + if test "$have_gl" = yes ; then + AC_CHECK_X_HEADER(GL/glx.h, have_gl=yes, have_gl=no, + [#include ]) + fi + + # If we have the headers, try and figure out which vendor it's from. + # + if test "$have_gl" = yes ; then + + # We need to know whether it's MesaGL so that we know which libraries + # to link against. + # + AC_CACHE_CHECK([whether GL is really MesaGL], ac_cv_have_mesa_gl, + [ac_cv_have_mesa_gl=no + if test "$ac_macosx" = no; then + # WTF! MacOS 10.5.0 ships the Mesa GL headers! + # It's not really Mesa, is it? + AC_EGREP_X_HEADER(Mesa|MESA, GL/glx.h, [ac_cv_have_mesa_gl=yes]) + fi]) + ac_have_mesa_gl=$ac_cv_have_mesa_gl + + gl_lib_1="" + GL_LIBS="" + + if test "$ac_macosx" = yes; then + + # Without these, every link against libGL gets a bunch of useless + # warnings. + # + osx_crud="-bind_at_load -multiply_defined suppress" + AC_MSG_RESULT(adding "$osx_crud" to GL_LIBS) + GL_LIBS="$GL_LIBS $osx_crud" + unset osx_crud + + # New lossage in 10.5.0: without this, we get: + # ld: cycle in dylib re-exports with /usr/X11/lib/libGL.dylib + # + osx_crud="/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib" + osx_crud="-Wl,-dylib_file,${osx_crud}:${osx_crud}" + + AC_MSG_RESULT(adding "$osx_crud" to GL_LIBS) + GL_LIBS="$GL_LIBS $osx_crud" + unset osx_crud + + # New lossage in 10.6.8: we can't allow -L/opt/local/lib to be in the + # link line, or at runtime XQueryExtension gets a segv due to some kind + # of library version skew. Libs must come from /usr/X11/lib even if + # $prefix and/or $exec_prefix are set to /opt/local/. + # + AC_MSG_RESULT(omitting "$libdir" from LDFLAGS) + libdir='' + + fi + + + # Some versions of MesaGL are compiled to require -lpthread. + # So if the Mesa headers exist, and -lpthread exists, then always + # link -lpthread after the Mesa libs (be they named -lGL or -lMesaGL.) + # + if test "$ac_have_mesa_gl" = yes; then + AC_CHECK_LIB(pthread, pthread_create, [GL_LIBS="-lpthread"], [],) + fi + + + # If we have Mesa headers, check to see if we can link against -lMesaGL. + # If we don't have Mesa headers, or we don't have -lMesaGL, try -lGL. + # Else, warn that GL is busted. (We have the headers, but no libs.) + # + + if test "$ac_have_mesa_gl" = yes ; then + AC_CHECK_X_LIB(MesaGL, glXCreateContext, + [gl_lib_1="MesaGL" + GL_LIBS="-lMesaGL -lMesaGLU $VIDMODE_LIBS $GL_LIBS"], + [], -lMesaGLU $GL_LIBS -lX11 -lXext $VIDMODE_LIBS -lm) + fi + + if test "$gl_lib_1" = "" ; then + AC_CHECK_X_LIB(GL, glXCreateContext, + [gl_lib_1="GL" + GL_LIBS="-lGL -lGLU $VIDMODE_LIBS $GL_LIBS"], + [], -lGLU $GL_LIBS -lX11 -lXext $VIDMODE_LIBS -lm) + fi + + if test "$gl_lib_1" = "" ; then + # we have headers, but no libs -- bail. + have_gl=no + ac_have_mesa_gl=no + gl_halfassed=yes + else + # linking works -- we can build the GL hacks. + AC_DEFINE(HAVE_GL) + if test "$ac_have_mesa_gl" = yes ; then + AC_DEFINE(HAVE_MESA_GL) + fi + fi + fi + + + # Now that we know we have GL headers and libs, do some more GL testing. + # + + if test "$have_gl" = yes ; then + # If it's MesaGL, we'd like to issue a warning if the version number + # is less than or equal to 2.6, because that version had a security bug. + # + if test "$ac_have_mesa_gl" = yes; then + + AC_CACHE_CHECK([MesaGL version number], ac_cv_mesagl_version_string, + [cat > conftest.$ac_ext < +#ifndef MESA_MAJOR_VERSION +# include +# ifdef XMESA_MAJOR_VERSION + /* Around Mesa 3.2, they took out the Mesa version number, so instead, + we have to check the XMesa version number (the number of the X protocol + support, which seems to be the same as the Mesa version number.) + */ +# define MESA_MAJOR_VERSION XMESA_MAJOR_VERSION +# define MESA_MINOR_VERSION XMESA_MINOR_VERSION +# else + /* Oh great. Some time after 3.4, they took out the xmesa.h header file, + so we have no way of telling what version of Mesa this is at all. + So, we'll guess that the osmesa version (the "offscreen protocol") + is less than or equal to the real mesa version number. Except that + if OSmesa is 3.3, assume at least Mesa 3.4, since OSmesa was 3.3 in + Mesa 3.4. And Mesa 3.3 had xmesa.h. What a complete load of shit! + */ +# include +# define MESA_MAJOR_VERSION OSMESA_MAJOR_VERSION +# define MESA_MINOR_VERSION OSMESA_MINOR_VERSION or newer, probably? +# if OSMESA_MAJOR_VERSION == 3 && OSMESA_MINOR_VERSION == 3 +# undef MESA_MINOR_VERSION +# define MESA_MINOR_VERSION 4 or newer, probably? +# endif +# endif +#endif +configure: MESA_MAJOR_VERSION MESA_MINOR_VERSION +EOF + + ac_save_CPPFLAGS="$CPPFLAGS" + if test \! -z "$includedir" ; then + CPPFLAGS="$CPPFLAGS -I$includedir" + fi + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + + mglv=`(eval "$ac_cpp conftest.$ac_ext") 2>&AC_FD_CC | grep configure:` + + # M4 sucks!! + changequote(X,Y) + mglv=`echo "$mglv" | sed -n \ + 's/^configure: *\([0-9][0-9]*\) *\([0-9].*\)$/\1.\2/p'` + changequote([,]) + + rm -f conftest.$ac_ext + + CPPFLAGS="$ac_save_CPPFLAGS" + + if test "$mglv" = ""; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + else + ac_mesagl_version_string="$mglv" + # M4 sucks!! + changequote(X,Y) + maj=`echo "$mglv" | sed -n 's/^\([0-9][0-9]*\)\..*$/\1/p'` + min=`echo "$mglv" | sed -n 's/^.*\.\([0-9][0-9]*\).*$/\1/p'` + changequote([,]) + ac_mesagl_version=`echo "$maj * 1000 + $min" | bc` + if test -z "$ac_mesagl_version"; then + ac_mesagl_version=unknown + ac_mesagl_version_string=unknown + fi + fi + ac_cv_mesagl_version=$ac_mesagl_version + ac_cv_mesagl_version_string=$ac_mesagl_version_string + ]) + ac_mesagl_version=$ac_cv_mesagl_version + ac_mesagl_version_string=$ac_cv_mesagl_version_string + fi + + + # Check for OpenGL 1.1 features. + # + AC_CHECK_X_LIB($gl_lib_1, glBindTexture, [AC_DEFINE(HAVE_GLBINDTEXTURE)], + [true], $GL_LIBS -lX11 -lXext -lm) + fi + +elif test "$with_gl" != no; then + echo "error: must be yes or no: --with-gl=$with_gl" + exit 1 +fi + + +############################################################################### +# +# Check for -lgle. +# +############################################################################### + +have_gle=no +with_gle_req=unspecified +gle_halfassed=no +AC_ARG_WITH(gle, +[ --with-gle Build those demos which depend on GLE + (the OpenGL "extrusion" library.)], + [with_gle="$withval"; with_gle_req="$withval"],[with_gle=yes]) + +HANDLE_X_PATH_ARG(with_gle, --with-gle, GLE) + +GLE_LIBS="" + +if test "$have_gl" = no ; then + true +elif test "$with_gle" = yes; then + + AC_CHECK_X_HEADER(GL/gle.h, have_gle3=yes, have_gle3=no, + [#include ]) + if test "$have_gle3" = yes ; then + have_gle=yes; + else + AC_CHECK_X_HEADER(GL/gutil.h, have_gle=yes, have_gle=no, + [#include ]) + if test "$have_gle" = yes ; then + AC_CHECK_X_HEADER(GL/tube.h, have_gle=yes, have_gle=no, + [#include ]) + fi + fi + + if test "$have_gle" = yes ; then + have_gle=no + gle_halfassed=yes + AC_CHECK_X_LIB(gle, gleCreateGC, + [have_gle=yes; gle_halfassed=no; GLE_LIBS="-lgle"], + [], $GL_LIBS -lX11 -lXext -lm) + fi + if test "$have_gle" = yes ; then + have_gle=no + gle_halfassed=yes + + # sometimes the libmatrix stuff is included in libgle. look there first. +# +# I don't get it. For some reason, this test passes on SGI, as if +# uview_direction_d() was in libgle -- but it's not, it's in libmatrix. +# Yet the link is succeeding. Why??? +# +# AC_CHECK_X_LIB(gle, uview_direction_d, +# [have_gle=yes; gle_halfassed=no], +# [], $GL_LIBS -lX11 -lXext -lm) + + # As of GLE 3 this is in libgle, and has changed name to uview_direction! + # *sigh* + if test "$have_gle3" = yes ; then + AC_CHECK_X_LIB(gle, uview_direction, + [have_gle=yes; gle_halfassed=no], + [], $GL_LIBS -lX11 -lXext -lm) + fi + # if it wasn't in libgle, then look in libmatrix. + if test "$have_gle" = no ; then + AC_CHECK_X_LIB(matrix, uview_direction_d, + [have_gle=yes; gle_halfassed=no; + GLE_LIBS="$GLE_LIBS -lmatrix"], + [], $GL_LIBS -lX11 -lXext -lm) + fi + fi + + if test "$have_gle" = yes ; then + AC_DEFINE(HAVE_GLE) + if test "$have_gle3" = yes ; then + AC_DEFINE(HAVE_GLE3) + fi + fi + +elif test "$with_gle" != no; then + echo "error: must be yes or no: --with-gle=$with_gle" + exit 1 + +fi + + +############################################################################### +# +# Handle --with-gles +# +############################################################################### + +with_gles_req=unspecified +AC_ARG_WITH(gles, +[ --with-gles Target OpenGL ES 1.x API instead of OpenGL 1.3.], + [with_gles="$withval"; with_gles_req="$withval"],[with_gles=no]) + +HANDLE_X_PATH_ARG(with_gles, --with-gles, JWZGLES) + +if test "$with_gles" = yes; then + have_gles=yes + AC_DEFINE(HAVE_JWZGLES) + JWZGLES_OBJS="jwzgles.o" + AC_MSG_RESULT(using OpenGL ES compatiblity shim) +elif test "$with_gles" != no; then + echo "error: must be yes or no: --with-gles=$with_xpm" + exit 1 +fi + +# May want to phase out glBitmap even in a non-GLES world. +# +if test "$have_gles" = yes; then + GLFPS_OBJS="fps-gl.o glxfonts.o texfont.o" + GLFONT_OBJS="" +else + AC_DEFINE(HAVE_GLBITMAP) + GLFPS_OBJS="fps-gl.o glxfonts.o" + GLFONT_OBJS="texfont.o" +fi + + +############################################################################### +# +# Check for -lgdk_pixbuf. +# These tests are for gdk_pixbuf usage of the hacks, +# not xscreensaver-demo (thus we have to test again to get +# the libraries right: don't want to pull in all of GTK +# for the hacks.) +# +############################################################################### + +have_gdk_pixbuf=no +with_gdk_pixbuf_req=unspecified +AC_ARG_WITH(pixbuf, +[ --with-pixbuf Include support for the GDK-Pixbuf library in some + demos, which will make it possible for them to read + GIF, JPEG, and PNG files as well.], + [with_gdk_pixbuf="$withval"; with_gdk_pixbuf_req="$withval"], + [with_gdk_pixbuf=yes]) + +# if --with-pixbuf=/directory/ was specified, remember that directory so that +# we can also look for the `gdk-pixbuf-config' program in that directory. +case "$with_gdk_pixbuf" in + /*) + gdk_pixbuf_dir="$with_gdk_pixbuf" + ;; + *) + gdk_pixbuf_dir="" + ;; +esac + +HANDLE_X_PATH_ARG(with_gdk_pixbuf, --with-pixbuf, GDK_PIXBUF) + +if test "$with_gdk_pixbuf" != yes -a "$with_gdk_pixbuf" != no ; then + echo "error: must be yes or no: --with-pixbuf=$with_gdk_pixbuf" + exit 1 +fi + +if test "$with_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + + pkgs='' + ok="yes" + + pkg_check_version gdk-pixbuf-2.0 2.0.0 + pkg_check_version gdk-pixbuf-xlib-2.0 2.0.0 + have_gdk_pixbuf="$ok" + + if test "$have_gdk_pixbuf" = yes; then + AC_CACHE_CHECK([for gdk-pixbuf includes], ac_cv_gdk_pixbuf_config_cflags, + [ac_cv_gdk_pixbuf_config_cflags=`$pkg_config --cflags $pkgs`]) + AC_CACHE_CHECK([for gdk-pixbuf libs], ac_cv_gdk_pixbuf_config_libs, + [ac_cv_gdk_pixbuf_config_libs=`$pkg_config --libs $pkgs`]) + fi + + ac_gdk_pixbuf_config_cflags=$ac_cv_gdk_pixbuf_config_cflags + ac_gdk_pixbuf_config_libs=$ac_cv_gdk_pixbuf_config_libs + + + if test "$have_gdk_pixbuf" = yes; then + # + # we appear to have pixbuf; check for headers/libs to be sure. + # + ac_save_gdk_pixbuf_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ac_gdk_pixbuf_config_cflags" + + have_gdk_pixbuf=no + + # check for header A... + AC_CHECK_X_HEADER(gdk-pixbuf/gdk-pixbuf.h, [have_gdk_pixbuf=yes]) + + # if that worked, check for header B... + if test "$have_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + gdk_pixbuf_halfassed=yes + AC_CHECK_X_HEADER(gdk-pixbuf/gdk-pixbuf-xlib.h, + [have_gdk_pixbuf=yes + gdk_pixbuf_halfassed=no]) + + # yay, it has a new name in Gtk 2.x... + if test "$have_gdk_pixbuf" = no; then + have_gdk_pixbuf=no + gdk_pixbuf_halfassed=yes + AC_CHECK_X_HEADER(gdk-pixbuf-xlib/gdk-pixbuf-xlib.h, + [have_gdk_pixbuf=yes + gdk_pixbuf_halfassed=no]) + fi + fi + CPPFLAGS="$ac_save_gdk_pixbuf_CPPFLAGS" + fi + + if test "$have_gdk_pixbuf" = yes; then + # we have the headers, now check for the libraries + have_gdk_pixbuf=no + gdk_pixbuf_halfassed=yes + + AC_MSG_RESULT(checking for gdk_pixbuf usability...) + + # library A... + AC_CHECK_X_LIB(c, gdk_pixbuf_new_from_file, [have_gdk_pixbuf=yes],, + $ac_gdk_pixbuf_config_libs -lX11 -lXext -lm) + # library B... + if test "$have_gdk_pixbuf" = yes; then + have_gdk_pixbuf=no + AC_CHECK_X_LIB(c, gdk_pixbuf_xlib_init, + [have_gdk_pixbuf=yes + gdk_pixbuf_halfassed=no],, + $ac_gdk_pixbuf_config_libs -lX11 -lXext -lm) + fi + fi + + if test "$have_gdk_pixbuf" = yes; then + INCLUDES="$INCLUDES $ac_gdk_pixbuf_config_cflags" + XPM_LIBS="$ac_gdk_pixbuf_config_libs" + AC_DEFINE(HAVE_GDK_PIXBUF) + else + AC_MSG_RESULT(checking for gdk_pixbuf usability... no) + fi + + if test "$have_gdk_pixbuf" = yes; then + AC_CHECK_X_LIB(c, gdk_pixbuf_apply_embedded_orientation, + [AC_DEFINE(HAVE_GDK_PIXBUF_APPLY_EMBEDDED_ORIENTATION)],, + $ac_gdk_pixbuf_config_libs -lX11 -lXext -lm) + fi +fi + + +############################################################################### +# +# Check for -lXpm. +# +############################################################################### + +have_xpm=no +with_xpm_req=unspecified +AC_ARG_WITH(xpm, +[ --with-xpm Include support for XPM files in some demos. + (Not needed if Pixbuf is used.)], + [with_xpm="$withval"; with_xpm_req="$withval"],[with_xpm=yes]) + +HANDLE_X_PATH_ARG(with_xpm, --with-xpm, XPM) + +if test "$with_xpm" = yes; then + AC_CHECK_X_HEADER(X11/xpm.h, + [have_xpm=yes + AC_DEFINE(HAVE_XPM) + XPM_LIBS="-lXpm $XPM_LIBS"],, + [#include ]) +elif test "$with_xpm" != no; then + echo "error: must be yes or no: --with-xpm=$with_xpm" + exit 1 +fi + +# See comment near $motif_requires_xpm, above. +# Need to do this here, after both Motif and XPM have been checked for. +# +if test "$have_motif" = yes -a "$have_xpm" = yes ; then + if test "$motif_requires_xpm" = yes ; then + MOTIF_LIBS="$MOTIF_LIBS $XPM_LIBS" + fi +fi + +if test "$XPM_LIBS" = "" ; then + XPM_LIBS=$(MINIXPM) +fi + + +############################################################################### +# +# Check for -ljpeg +# +############################################################################### + +have_jpeg=no +with_jpeg_req=unspecified +jpeg_halfassed=no +AC_ARG_WITH(jpeg, +[ --with-jpeg Include support for the JPEG library.], + [with_jpeg="$withval"; with_jpeg_req="$withval"], + [with_jpeg=yes]) + +HANDLE_X_PATH_ARG(with_jpeg, --with-jpeg, JPEG) + +if test "$with_jpeg" != yes -a "$with_jpeg" != no ; then + echo "error: must be yes or no: --with-jpeg=$with_jpeg" + exit 1 +fi + +if test "$with_jpeg" = yes; then + + have_jpeg=no + AC_CHECK_X_HEADER(jpeglib.h, [have_jpeg=yes]) + + if test "$have_jpeg" = yes; then + # we have the header, now check for the library + have_jpeg=no + jpeg_halfassed=yes + AC_CHECK_X_LIB(jpeg, jpeg_start_compress, + [have_jpeg=yes + jpeg_halfassed=no + JPEG_LIBS="-ljpeg" + AC_DEFINE(HAVE_JPEGLIB)]) + fi +fi + + +############################################################################### +# +# Check for pty support: this allows 'phosphor' and 'apple2' +# to run curses-based programs, or be used as terminal windows. +# +############################################################################### + +PTY_LIBS= +AC_CHECK_HEADERS(pty.h util.h) +AC_CHECK_X_LIB(util, forkpty, + [PTY_LIBS="-lutil" + ac_have_forkpty=yes + AC_DEFINE(HAVE_FORKPTY)]) + +if test "$ac_have_forkpty" != yes ; then + # we don't need (or have) -lutil on MacOS 10.4.2... + AC_CHECK_X_LIB(c, forkpty, + [PTY_LIBS="" + AC_DEFINE(HAVE_FORKPTY)]) +fi + +############################################################################### +# +# Check for the XSHM server extension. +# +############################################################################### + +have_xshm=no +with_xshm_req=unspecified +AC_ARG_WITH(xshm-ext, +[ --with-xshm-ext Include support for the Shared Memory extension.], + [with_xshm="$withval"; with_xshm_req="$withval"],[with_xshm=yes]) + +HANDLE_X_PATH_ARG(with_xshm, --with-xshm-ext, XSHM) + +if test "$with_xshm" = yes; then + + # first check for Xshm.h. + AC_CHECK_X_HEADER(X11/extensions/XShm.h, [have_xshm=yes],, + [#include ]) + + # if that succeeded, then check for sys/ipc.h. + if test "$have_xshm" = yes; then + have_xshm=no + AC_CHECK_X_HEADER(sys/ipc.h, [have_xshm=yes]) + fi + + # if that succeeded, then check for sys/shm.h. + if test "$have_xshm" = yes; then + have_xshm=no + AC_CHECK_X_HEADER(sys/shm.h, [have_xshm=yes]) + fi + + # AIX is pathological, as usual: apparently it's normal for the Xshm headers + # to exist, but the library code to not exist. And even better, the library + # code is in its own library: libXextSam.a. So, if we're on AIX, and that + # lib doesn't exist, give up. (This lib gets added to X_EXTRA_LIBS, and + # that's not quite right, but close enough.) + # + case "$host" in + *-aix*) + if [ `uname -v` -eq 3 ]; then + have_xshm=no + AC_CHECK_X_LIB(XextSam, XShmQueryExtension, + [have_xshm=yes; X_EXTRA_LIBS="$X_EXTRA_LIBS -lXextSam"], + [true], -lX11 -lXext -lm) + fi + ;; + esac + + # if that succeeded, then we've really got it. + if test "$have_xshm" = yes; then + AC_DEFINE(HAVE_XSHM_EXTENSION) + fi + +elif test "$with_xshm" != no; then + echo "error: must be yes or no: --with-xshm-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the DOUBLE-BUFFER server extension. +# +############################################################################### + +have_xdbe=no +with_xdbe_req=unspecified +AC_ARG_WITH(xdbe-ext, +[ --with-xdbe-ext Include support for the DOUBLE-BUFFER extension.], + [with_xdbe="$withval"; with_xdbe_req="$withval"],[with_xdbe=yes]) + +HANDLE_X_PATH_ARG(with_xdbe, --with-xdbe-ext, DOUBLE-BUFFER) + +if test "$with_xdbe" = yes; then + + AC_CHECK_X_HEADER(X11/extensions/Xdbe.h, [have_xdbe=yes],, + [#include ]) + if test "$have_xdbe" = yes; then + AC_DEFINE(HAVE_DOUBLE_BUFFER_EXTENSION) + fi + +elif test "$with_xdbe" != no; then + echo "error: must be yes or no: --with-xdbe-ext=$with_xshm" + exit 1 +fi + + +############################################################################### +# +# Check for the SGI XReadDisplay server extension. +# +# Note: this has to be down here, rather than up with the other server +# extension tests, so that the output of `configure --help' is in the +# right order. Arrgh! +# +############################################################################### + +have_readdisplay=no +with_readdisplay_req=unspecified +AC_ARG_WITH(readdisplay, +[ --with-readdisplay Include support for the XReadDisplay extension.], + [with_readdisplay="$withval"; with_readdisplay_req="$withval"], + [with_readdisplay=yes]) + +HANDLE_X_PATH_ARG(with_readdisplay, --with-readdisplay, XReadDisplay) + +if test "$with_readdisplay" = yes; then + AC_CHECK_X_HEADER(X11/extensions/readdisplay.h, + AC_DEFINE(HAVE_READ_DISPLAY_EXTENSION),, + [#include ]) +elif test "$with_readdisplay" != no; then + echo "error: must be yes or no: --with-readdisplay=$with_readdisplay" + exit 1 +fi + + +############################################################################### +# +# Check for a directory full of images to use as the default value +# of the "imageDirectory" preference. +# +############################################################################### + +have_imagedir=no +with_imagedir_req=unspecified + +AC_ARG_WITH(image-directory, +[ --with-image-directory Arg is the default directory from which some demos + will choose random images to display.], + [with_imagedir="$withval"; with_imagedir_req="$withval"], + [with_imagedir=yes]) +# no HANDLE_X_PATH_ARG for this one + +case "$with_imagedir" in + /*) + # absolute path + AC_MSG_CHECKING([for image directory $with_imagedir]) + if test -d "$with_imagedir" ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + with_imagedir="" + fi + ;; + yes) + with_imagedir="" + + #### Could use some more defaults here... + for dd in \ + "/usr/share/backgrounds/images/" \ + "/usr/share/wallpapers/" \ + "/Library/Desktop Pictures/" \ + ; do + if test -z "$with_imagedir"; then + AC_MSG_CHECKING([for image directory $dd]) + if test -d "$dd" ; then + AC_MSG_RESULT(yes) + with_imagedir="$dd" + else + AC_MSG_RESULT(no) + fi + fi + done + + ;; + no) + with_imagedir="" + ;; + + *) + echo "error: must be an absolute path: --with-image-directory=$with_imagedir_req" + exit 1 + ;; +esac +ac_cv_imagedir="$with_imagedir" + +DEFAULT_IMAGES_P='True' +DEFAULT_IMAGE_DIRECTORY="$ac_cv_imagedir" + +if test -z "$DEFAULT_IMAGE_DIRECTORY" ; then + DEFAULT_IMAGES_P='False' +fi + + +############################################################################### +# +# Pick a text file to use as the default of the "textFile" preference. +# Any old file will do, but preferably one that will make interesting +# shapes when displayed by "starwars" and "fontglide". +# +############################################################################### + +have_textfile=no +with_textfile_req=unspecified + +AC_ARG_WITH(text-file, +[ --with-text-file=FILE By default, some demos may display this file.], + [with_textfile="$withval"; with_textfile_req="$withval"], + [with_textfile=yes]) +# no HANDLE_X_PATH_ARG for this one + +case "$with_textfile" in + /*) + # absolute path + AC_MSG_CHECKING([for text file $with_textfile]) + if test -f "$with_textfile" ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + with_textfile="" + fi + ;; + yes) + with_textfile="" + + #### Could use some more defaults here... + for f in \ + "/usr/X11R6/lib/X11/doc/README" \ + "/usr/share/doc/xserver-common/copyright" \ + "/usr/share/doc/xserver-xorg-core/copyright" \ + "/usr/X11R6/README" \ + "/usr/share/doc/libX11*/COPYING" \ + "/usr/X11/share/X11/doc/README*" \ + "/usr/share/doc/debian/debian-manifesto" \ + ; do + if test -z "$with_textfile"; then + AC_MSG_CHECKING([for text file $f]) + f=`/bin/ls $f 2>&- | head -1` + if test -f "$f" ; then + AC_MSG_RESULT(yes) + with_textfile="$f" + else + AC_MSG_RESULT(no) + fi + fi + done + + ;; + no) + with_textfile="" + ;; + + *) + echo "error: must be an absolute path: --with-text-file=$with_textfile_req" + exit 1 + ;; +esac +ac_cv_textfile="$with_textfile" + +DEFAULT_TEXT_FILE="$ac_cv_textfile" + + +############################################################################### +# +# Check the browser to see help URL +# +############################################################################### + +have_browser=no +with_browser_req=unspecified + +AC_ARG_WITH(browser, +[ --with-browser=BROWSER Specify the web browser used to show the help URL.], + [with_browser="$withval"; with_browser_req="$withval"], + [with_browser=no ]) +# no HANDLE_X_PATH_ARG for this one + +case "$with_browser" in + no ) + ;; + * ) + WITH_BROWSER=$with_browser + gnome_open_program=$with_browser + AC_MSG_CHECKING([for browser $with_browser]) + with_browser_fullpath=`which $with_browser 2>/dev/null` + case $with_browser_fullpath in + /* ) + AC_MSG_RESULT(yes) + have_browser=yes + ;; + * ) + AC_MSG_RESULT(no) +# Only warning: we don't want to install all packages for the +# dependency of the browser in building stage... + echo "WARNING: browser not found: --with-browser=$with_browser" + ;; + esac + ;; +esac +ac_cv_browser="$with_browser" + +############################################################################### +# +# Check whether it's ok to install some hacks as setuid (e.g., "sonar") +# This should be safe, but let's give people the option. +# +############################################################################### + +setuid_hacks_default=no +setuid_hacks="$setuid_hacks_default" +AC_ARG_WITH(setuid-hacks, +[ --with-setuid-hacks Allow some demos to be installed `setuid root' + (which is needed in order to ping other hosts.) +], + [setuid_hacks="$withval"], [setuid_hacks="$setuid_hacks_default"]) + +HANDLE_X_PATH_ARG(setuid_hacks, --with-setuid-hacks, setuid hacks) + +if test "$setuid_hacks" = yes; then + true +elif test "$setuid_hacks" != no; then + echo "error: must be yes or no: --with-setuid-hacks=$setuid_hacks" + exit 1 +fi + + +############################################################################### +# +# Done testing. Now, set up the various -I and -L variables, +# and decide which GUI program to build by default. +# +############################################################################### + +DEPEND=makedepend +DEPEND_FLAGS= +DEPEND_DEFINES= + + +if test \! -z "$includedir" ; then + INCLUDES="$INCLUDES -I$includedir" +fi + +if test \! -z "$libdir" ; then + LDFLAGS="$LDFLAGS -L$libdir" +fi + + +PREFERRED_DEMO_PROGRAM='' +ALL_DEMO_PROGRAMS= +if test "$have_motif" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Xm + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi +if test "$have_gtk" = yes; then + PREFERRED_DEMO_PROGRAM=xscreensaver-demo-Gtk + ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" +fi + + +if test "$have_kerberos" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(KERBEROS_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(KERBEROS_OBJS)" +fi +if test "$have_pam" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(PAM_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PAM_OBJS)" + INSTALL_PAM="install-pam" +fi +if test "$enable_pam_check_account_type" = yes; then + COMMENT_PAM_CHECK_ACCOUNT="" +else + COMMENT_PAM_CHECK_ACCOUNT="#" +fi +if test "$have_passwd_helper" = yes; then + PASSWD_SRCS="$PASSWD_SRCS \$(PWHELPER_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PWHELPER_OBJS)" +fi + PASSWD_SRCS="$PASSWD_SRCS \$(PWENT_SRCS)" + PASSWD_OBJS="$PASSWD_OBJS \$(PWENT_OBJS)" + + +if test "$enable_locking" = yes; then + LOCK_SRCS='$(LOCK_SRCS_1) $(PASSWD_SRCS)' + LOCK_OBJS='$(LOCK_OBJS_1) $(PASSWD_OBJS)' +else + LOCK_SRCS='$(NOLOCK_SRCS_1)' + LOCK_OBJS='$(NOLOCK_OBJS_1)' +fi + +if test "$ac_macosx" = yes; then + EXES_OSX='$(EXES_OSX)' + SCRIPTS_OSX='$(SCRIPTS_OSX)' + MEN_OSX='$(MEN_OSX)' +else + EXES_OSX= + SCRIPTS_OSX= + MEN_OSX= +fi + + +INSTALL_SETUID='$(INSTALL_PROGRAM) $(SUID_FLAGS)' + +if test "$need_setuid" = yes; then + NEED_SETUID=yes +else + NEED_SETUID=no +fi + +if test "$setuid_hacks" = yes; then + SETUID_HACKS=yes +else + SETUID_HACKS=no +fi + +tab=' ' +if test "$have_gl" = yes; then + GL_EXES='$(GL_EXES)' + SUID_EXES='$(SUID_EXES)' + RETIRED_GL_EXES='$(RETIRED_GL_EXES)' + GL_UTIL_EXES='$(GL_UTIL_EXES)' + GL_MEN='$(GL_MEN)' + GL_KLUDGE=" " +else + GL_KLUDGE="-" +fi + +if test "$have_gle" = yes; then + GLE_EXES='$(GLE_EXES)' + GLE_KLUDGE=" " +else + GLE_KLUDGE="-" +fi + +if test "$have_jpeg" = yes -a "$have_gdk_pixbuf" = yes; then + JPEG_EXES='$(JPEG_EXES)' +fi + + +# Another substitution in the XScreenSaver.ad.in file: +# +if test "$gnome_open_program" != ''; then + GNOME24='' + GNOME22='! ' + NOGNOME='! ' +elif test "$gnome_url_show_program" != ''; then + GNOME24='! ' + GNOME22='' + NOGNOME='! ' +else + GNOME24='! ' + GNOME22='! ' + NOGNOME='' +fi + + +# Set PO_DATADIR to something sensible. +# +AC_MSG_CHECKING([for locale directory]) +if test -n "$GTK_DATADIR" ; then + PO_DATADIR="$GTK_DATADIR" +elif test "$have_gtk" = yes; then + PO_DATADIR=`$pkg_config --variable=prefix gtk+-2.0` + PO_DATADIR="$PO_DATADIR/share" +fi + +if test -z "$PO_DATADIR" ; then + # + # #### Total fucking kludge -- + # Map /build/prefix/usr/X11R6/share/ to /build/prefix/usr/share/ + # but of course we need to expand all the nested variables to do that... + # + dd=`eval eval eval eval eval eval eval eval eval eval eval echo $datadir` + PO_DATADIR=`echo $dd | sed 's@/X11R6/@/@'` +fi + +AC_MSG_RESULT($PO_DATADIR/locale) + + +# canonicalize slashes. +HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` + +# gcc 3.0 likes to issue this warning for every file: +# +# cc1: warning: changing search order for system directory "/usr/local/include" +# cc1: warning: as it has already been specified as a non-system directory +# +# Yay. We can only avoid that by deleting "-I${prefix}/include" from the list. +# Which *should* be totally redundant, and thus an ok thing to delete? +# +INCLUDES=`echo "$INCLUDES" | sed 's@ -I${prefix}/include@@g;'` + + +############################################################################### +# +# Perform substitutions and write Makefiles. +# +############################################################################### + +AC_SUBST(INCLUDES) + +AC_SUBST(PREFERRED_DEMO_PROGRAM) +AC_SUBST(ALL_DEMO_PROGRAMS) +AC_SUBST(SAVER_LIBS) +AC_SUBST(MOTIF_LIBS) +AC_SUBST(GTK_LIBS) +AC_SUBST(XML_LIBS) +AC_SUBST(JPEG_LIBS) +AC_SUBST(HACK_LIBS) +AC_SUBST(XPM_LIBS) +AC_SUBST(PTY_LIBS) +AC_SUBST(GL_LIBS) +AC_SUBST(GLE_LIBS) +AC_SUBST(XDPMS_LIBS) +AC_SUBST(XINERAMA_LIBS) +AC_SUBST(PASSWD_LIBS) +AC_SUBST(INSTALL_SETUID) +AC_SUBST(SETUID_HACKS) +AC_SUBST(INSTALL_DIRS) +AC_SUBST(NEED_SETUID) +AC_SUBST(INSTALL_PAM) +AC_SUBST(HAVE_PAM_FAIL_DELAY) +AC_SUBST(COMMENT_PAM_CHECK_ACCOUNT) +AC_SUBST(NEW_LOGIN_COMMAND) +AC_SUBST(NEW_LOGIN_COMMAND_P) +AC_SUBST(DEFAULT_IMAGES_P) +AC_SUBST(DEFAULT_IMAGE_DIRECTORY) +AC_SUBST(DEFAULT_TEXT_FILE) +AC_SUBST(WITH_BROWSER) + +AC_SUBST(OBJCC) +AC_SUBST(EXES_OSX) +AC_SUBST(SCRIPTS_OSX) +AC_SUBST(MEN_OSX) + +AC_SUBST(PASSWD_SRCS) +AC_SUBST(PASSWD_OBJS) +AC_SUBST(XMU_SRCS) +AC_SUBST(XMU_OBJS) +AC_SUBST(XMU_LIBS) +AC_SUBST(SAVER_GL_SRCS) +AC_SUBST(SAVER_GL_OBJS) +AC_SUBST(SAVER_GL_LIBS) +AC_SUBST(LOCK_SRCS) +AC_SUBST(LOCK_OBJS) +AC_SUBST(JPEG_EXES) +AC_SUBST(GL_EXES) +AC_SUBST(RETIRED_GL_EXES) +AC_SUBST(SUID_EXES) +AC_SUBST(GL_UTIL_EXES) +AC_SUBST(GL_MEN) +AC_SUBST(GL_KLUDGE) +AC_SUBST(GLE_EXES) +AC_SUBST(GLE_KLUDGE) +AC_SUBST(JWZGLES_OBJS) +AC_SUBST(GLFPS_OBJS) +AC_SUBST(GLFONT_OBJS) +AC_SUBST(GNOME24) +AC_SUBST(GNOME22) +AC_SUBST(NOGNOME) +AC_SUBST(HACKDIR) +AC_SUBST(HACKDIR_FULL) +AC_SUBST(GTK_DATADIR) +AC_SUBST(PO_DATADIR) +AC_SUBST(HACK_CONF_DIR) +AC_SUBST(GTK_EXTRA_OBJS) + +APPDEFAULTS=$ac_x_app_defaults +AC_SUBST(APPDEFAULTS) + +AC_SUBST(DEPEND) +AC_SUBST(DEPEND_FLAGS) +AC_SUBST(DEPEND_DEFINES) +AC_SUBST(PERL) + +AC_OUTPUT(Makefile + utils/Makefile + driver/Makefile + driver/xscreensaver.pam + hacks/Makefile + hacks/glx/Makefile + po/Makefile.in + driver/XScreenSaver.ad) + +############################################################################### +# +# Print some warnings at the end. +# +############################################################################### + +warn_prefix_1=" Warning:" +warn_prefix_2=" Note:" +warn_prefix="$warn_prefix_1" + +warning=no +warnsep=' #################################################################' + +warnpre() { + if test "$warning" = no ; then + echo '' ; echo "$warnsep" ; echo '' + warning=yes + fi +} + +warn() { + warnpre + if test "$warning" = long ; then echo '' ; fi + warning=yes + rest="$@" + echo "$warn_prefix $rest" +} + +warnL() { + was=$warning + warnpre + warning=yes + if test "$was" != no ; then echo '' ; fi + rest="$@" + echo "$warn_prefix $rest" +} + +warn2() { + rest="$@" + echo " $rest" + warning=long +} + +note() { + warn_prefix="$warn_prefix_2" + warn $@ + warn_prefix="$warn_prefix_1" +} + +noteL() { + warn_prefix="$warn_prefix_2" + warnL $@ + warn_prefix="$warn_prefix_1" +} + + +if test "$with_sgi_req" = yes -a "$have_sgi" = no ; then + warn 'The SGI saver extension was requested, but was not found.' +fi + +if test "$with_xidle_req" = yes -a "$have_xidle" = no ; then + warn 'The XIdle extension was requested, but was not found.' +fi + +if test "$with_xshm_req" = yes -a "$have_xshm" = no ; then + warn 'The XSHM extension was requested, but was not found.' +fi + +if test "$with_xdbe_req" = yes -a "$have_xdbe" = no ; then + warn 'The DOUBLE-BUFFER extension was requested, but was not found.' +fi + +if test "$with_sgivc_req" = yes -a "$have_sgivc" = no ; then + warn 'The SGI-VIDEO-CONTROL extension was requested, but was not found.' +fi + +if test "$with_dpms_req" = yes -a "$have_dpms" = no ; then + warn 'The DPMS extension was requested, but was not found.' +fi + +if test "$with_xinerama_req" = yes -a "$have_xinerama" = no ; then + warn 'The Xinerama extension was requested, but was not found.' +fi + +if test "$with_xf86vmode_req" = yes -a "$have_xf86vmode" = no ; then + warn 'The XF86VMODE extension was requested, but was not found.' +fi + +if test "$with_randr_req" = yes -a "$have_randr" = no ; then + warn 'The RANDR extension was requested, but was not found.' +fi + +if test "$with_proc_interrupts_req" = yes -a "$have_proc_interrupts" = no; then + warn "Checking of /proc/interrupts was requested, but it's bogus." +fi + +if test "$pkg_config" = false ; then + warnL 'The "pkg-config" program was not found. Without that,' + warn2 "detection of the various GTK libraries won't work." +else + pkgerr=`$pkg_config --list-all 2>&1 >/dev/null` + if test "x$pkgerr" != "x" ; then + warnL 'The "pkg-config" program produces errors. This often causes' + warn2 "detection of the various GTK libraries to malfunction." + warn2 "The errors are:" + echo '' + echo "$pkgerr" | sed 's/^/ > /g' + fi +fi + +if test "$gtk_halfassed" != no ; then + warnL "GTK version $gtk_halfassed was found, but at least one supporting" + warn2 "library ($gtk_halfassed_lib) was not, so GTK can't be used." + warn2 "Perhaps some of the development packages are not installed?" + if test "$have_gtk" = yes ; then + v="$ac_gtk_version_string" + warn2 "GTK $v is also installed, so it will be used instead." + warn2 "Please read the above output and the \`config.log' file" + warn2 "for more details." + fi +fi + +motif_warn2() { + warn2 'Though the Motif front-end to xscreensaver is still' + warn2 'maintained, it is no longer being updated with new' + warn2 'features: all new development on the xscreensaver-demo' + warn2 'program is happening in the GTK version, and not in the' + warn2 'Motif version. It is recommended that you build against' + warn2 'GTK instead of Motif. See .' +} + +if test "$have_motif" = no -a "$have_gtk" = no; then + + if test "$with_motif" = yes; then + warnL "Neither the GTK nor Motif libraries were found; the" + warn2 "\`xscreensaver-demo' program requires one of these." + echo '' + motif_warn2 + else + warnL "The GTK libraries do not seem to be available; the" + warn2 "\`xscreensaver-demo' program requires them." +# echo '' +# warn2 'You can use Motif or Lesstif instead of GTK (use the' +# warn2 "\`--with-motif' option) but that is NOT recommended." +# motif_warn2 + fi + +elif test "$with_motif_req" = yes -a "$have_motif" = no ; then + warnL "Use of Motif was requested, but it wasn't found;" + warn2 "Gtk will be used instead." + +elif test "$jurassic_gtk" = yes ; then + + pref_gtk=2.0 + + v="$ac_gtk_version_string" + if test "$with_gtk_req" = yes -a "$ac_gtk_version" = "unknown" ; then + warnL "Use of Gtk was requested, but its version number is unknown;" + elif test "$with_gtk_req" = yes ; then + warnL "Use of Gtk was requested, but it is version $v;" + else + warnL "Gtk was found on this system, but it is version $v;" + fi + + warn2 "Gtk $pref_gtk or newer is required." + +elif test "$with_gtk_req" = yes -a "$have_gtk" = no ; then + warnL "Use of Gtk was requested, but it wasn't found." +fi + + +if test "$have_gtk" = yes -a "$have_gdk_pixbuf" = no ; then + warn "GTK is being used, but the GDK-Pixbuf library and/or" + warn2 "headers were not found. That can't be good. Please" + warn2 "install the GDK-Pixbuf development kit and re-configure." +fi + +if test "$have_motif" = yes -a "$have_lesstif" = yes ; then + + preferred_lesstif=0.92 + + if test "$lesstif_version" = unknown; then + warnL "Unable to determine the LessTif version number!" + warn2 "Make sure you are using version $preferred_lesstif or newer." + warn2 "See ." + + elif test \! $lesstif_version -gt 82; then + warnL "LessTif version $lesstif_version_string is being used." + warn2 "LessTif versions 0.82 and earlier are too buggy to" + warn2 "use with XScreenSaver; it is strongly recommended" + warn2 "that you upgrade to at least version $preferred_lesstif!" + warn2 "See ." + fi +fi + + +if test "$have_motif" = yes -a "$have_gtk" = no ; then + warn 'Motif is being used, and GTK is not.' + echo '' + motif_warn2 +fi + + +if test "$with_xpm_req" = yes -a "$have_xpm" = no; then + warnL 'Use of XPM was requested, but it was not found.' +fi + +if test "$with_gdk_pixbuf_req" = yes -a "$have_gdk_pixbuf" = no; then + warnL 'Use of GDK-Pixbuf was requested, but it was not found.' +fi + +if test "$have_gdk_pixbuf" = no -o "$gdk_pixbuf_halfassed" = yes || \ + test "$have_gdk_pixbuf" = no -a "$have_xpm" = no ; then + + if test "$with_gdk_pixbuf_req" = yes ; then + true + elif test "$with_gdk_pixbuf_req" = no ; then + warnL 'The GDK-Pixbuf library is not being used.' + else + warnL 'The GDK-Pixbuf library was not found.' + fi + + if test "$with_xpm_req" = yes -o "$have_xpm" = yes ; then + true + elif test "$with_xpm_req" = no ; then + warnL 'The XPM library is not being used.' + else + warnL 'The XPM library was not found.' + fi + + if test "$have_gdk_pixbuf" = no -a "$have_xpm" = yes ; then + warn2 'The XPM library is being used instead.' + fi + + if test "$gdk_pixbuf_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either GDK-Pixbuf is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 'Some of the demos will not use images as much as they could.' + warn2 'You should consider installing GDK-Pixbuf and re-running' + warn2 'configure. (GDK-Pixbuf is recommended over XPM, as it' + warn2 'provides support for more image formats.)' +fi + + +if test "$have_jpeg" = no ; then + if test "$with_jpeg_req" = yes ; then + warnL 'Use of libjpeg was requested, but it was not found.' + elif test "$with_jpeg_req" = no ; then + noteL 'The JPEG library is not being used.' + else + noteL 'The JPEG library was not found.' + fi + + if test "$jpeg_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'library; so either JPEG is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + echo '' + fi + + if test "$have_gdk_pixbuf" = no ; then + warn2 "This means that it won't be possible for the image-manipulating" + warn2 "display modes to load files from disk; and it also means that" + warn2 "the \`webcollage' program will be much slower." + else + warn2 "This means the \`webcollage' program will be much slower." + fi +fi + + +if test "$have_gl" = yes -a "$ac_have_mesa_gl" = yes ; then + preferred_mesagl=3.4 + mgv="$ac_mesagl_version_string" + pgl="$preferred_mesagl" + + if test "$ac_mesagl_version" = unknown; then + true + # warnL "Unable to determine the MesaGL version number!" + # warn2 "Make sure you are using version $preferred_mesagl or newer." + + elif test \! "$ac_mesagl_version" -gt 2006; then + warnL "MesaGL version number is $mgv --" + warn2 "MesaGL 2.6 and earlier have a security bug. It is strongly" + warn2 "recommended that you upgrade to at least version $preferred_mesagl." + + elif test \! "$ac_mesagl_version" -gt 3003; then + warnL "MesaGL version number is $mgv --" + warn2 "MesaGL 3.3 and earlier have some bugs; it is recommended" + warn2 "that you upgrade to $pgl or newer." + fi +fi + +if test "$have_gl" = no ; then + if test "$with_gl_req" = yes ; then + warnL 'Use of GL was requested, but it was not found.' + elif test "$with_gl_req" = no ; then + noteL 'The OpenGL 3D library is not being used.' + else + noteL 'The OpenGL 3D library was not found.' + fi + + if test "$gl_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either GL is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 'Those demos which use 3D will not be built or installed.' + warn2 'You might want to consider installing OpenGL and' + warn2 "re-running configure. If your vendor doesn't ship" + warn2 'their own implementation of OpenGL, you can get a free' + warn2 'version at . For general OpenGL' + warn2 'info, see .' + +fi + + +if test "$have_gl" = yes -a "$have_gle" = no ; then + + # nobody cares about this; don't print the warning unless it was + # requested and not found, or halfway-found. + if test "$with_gle_req" = yes -o "$gle_halfassed" = yes ; then + + if test "$with_gle_req" = yes ; then + noteL 'Use of the GLE (GL Extrusion) library was requested, but' + warn2 'it was not found (though the OpenGL library was found, and' + warn2 'is being used.)' + elif test "$with_gle_req" = no ; then + noteL 'The OpenGL Library is being used, but the GLE (GL Extrusion)' + warn2 'library is not.' + else + noteL 'The OpenGL Library was found, but the GLE (GL Extrusion)' + warn2 'was not.' + fi + + if test "$gle_halfassed" = yes ; then + echo '' + warn2 'More specifically, we found the headers, but not the' + warn2 'libraries; so either GLE is half-installed on this' + warn2 "system, or something else went wrong. The \`config.log'" + warn2 'file might contain some clues.' + fi + + echo '' + warn2 'Some of the OpenGL (3D) demos (those that depend on GLE)' + warn2 'will not be built or installed. You might want to consider' + warn2 'installing GLE and re-running configure. You can find the' + warn2 'GLE library at . For general' + warn2 'OpenGL info, see .' + + fi +fi + + +if test "$with_readdisplay_req" = yes -a "$have_readdisplay" = no ; then + warn 'Use of XReadDisplay was requested, but it was not found.' +fi + +if test "$with_kerberos_req" = yes -a "$have_kerberos" = no ; then + warn 'Use of Kerberos was requested, but it was not found.' +fi + +if test "$with_pam_req" = yes -a "$have_pam" = no ; then + warn 'Use of PAM was requested, but it was not found.' +fi + +if test "$with_shadow_req" = yes -a "$have_shadow" = no ; then + warn 'Use of shadow passwords was requested, but they were not found.' +fi + +if test "$ac_macosx" = yes ; then + if test "$enable_locking" = yes ; then + warn "You have specified --enable-locking on MacOS X." + warn2 "THIS DOES NOT WORK! Don't do this!" + fi +fi + + +# You are in a twisty maze of namespaces and syntaxes, all alike. +# Fuck the skull of Unix. +# +bindir=`eval eval eval eval eval eval eval echo $bindir` +HACKDIR=`eval eval eval eval eval eval eval echo $HACKDIR` +HACK_CONF_DIR=`eval eval eval eval eval eval eval echo $HACK_CONF_DIR` + +# canonicalize slashes. +bindir=`echo "${bindir}" | sed 's@/$@@;s@//*@/@g'` +HACKDIR=`echo "${HACKDIR}" | sed 's@/$@@;s@//*@/@g'` +HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` + + +# Sanity check the hackdir +for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do + if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then + echo "" + AC_MSG_ERROR([\"--with-hackdir=${bindir}/${bad_choice}\" won't work. + There will be an executable installed with that name, so + that can't be the name of a directory as well. Please + re-configure with a different directory name.]) + fi +done + + +do_dir_warning=no + +# Now let's warn if there's a previous RPM version already installed. +# But don't bother with this test if we are currently *building* an RPM. + +if test -z "$RPM_PACKAGE_VERSION" ; then + + rpmnames="xscreensaver xscreensaver-base xscreensaver-extras" + + # M4 sucks!! + changequote(X,Y) + rpmv=`(rpm -qv $rpmnames) 2>/dev/null | \ + sed -n 's/^[-a-z]*-\([0-9][0-9]*[.][0-9][0-9a-z]*\)-.*$/\1/p' | \ + head -1` + changequote([,]) + + if test \! -z "$rpmv" ; then + rpmbdir=`rpm -ql $rpmnames | sed -n 's@^\(.*\)/xscreensaver-demo$@\1@p'` + rpmhdir=`rpm -ql $rpmnames | sed -n 's@^\(.*\)/popsquares$@\1@p'` + + warning=no + warnL "There is already an installed RPM of xscreensaver $rpmv" + warn2 'on this system. You might want to remove it ("rpm -ve")' + warn2 'before running "make install" in this directory.' + echo "" + warn2 "Alternately, you could build this version of xscreensaver" + warn2 'as an RPM, and then install that. An "xscreensaver.spec"' + warn2 'file is included. Try "rpmbuild -v -ba xscreensaver.spec".' + warn2 "See the RPM documentation for more info." + echo "" + + if test "$rpmbdir" = "$rpmhdir" ; then + warn2 "The RPM version was installed in $rpmbdir/." + do_dir_warning=yes + else + warn2 "The RPM version was installed in $rpmbdir/," + warn2 "with demos in $rpmhdir/." + fi + fi +fi + +# Also warn if there's a Debian package installed. +# +debnames="xscreensaver xscreensaver-data xscreensaver-data-extra" +debv='' +for dpkg in $debnames ; do + if test -z "$debv"; then + debv=`dpkg -s $dpkg 2>/dev/null | sed -n 's/^Version: \(.*\)$/\1/p'` + fi +done + +if test \! -z "$debv" ; then + debbdir=`dpkg -L $debnames 2>/dev/null | \ + sed -n 's@^\(.*/bin/\)xscreensaver$@\1@p'` + debhdir=`dpkg -L $debnames 2>/dev/null | \ + sed -n 's@^\(.*/\)popsquares$@\1@p'` + if test -z "$debbdir" ; then debbdir='???'; fi + if test -z "$debhdir" ; then debhdir='???'; fi + + warning=no + warnL "There is already an installed dpkg of xscreensaver" + warn2 "version \"$debv\" on this system." + echo "" + warn2 "The dpkg was installed in $debbdir," + warn2 "with demos in $debhdir." +fi + + +if test "${bindir}" = "${HACKDIR}" ; then + do_dir_warning=yes +fi + +if test "$do_dir_warning" = yes; then + echo "" + echo "$warnsep" + echo "" + echo ' When you run "make install", the "xscreensaver",' + echo ' "xscreensaver-demo", and "xscreensaver-command" executables' + echo " will be installed in ${bindir}/." + echo "" + echo " The various graphics demos (190+ different executables) will" + echo " be installed in ${HACKDIR}/." + echo "" + echo " If you would prefer the demos to be installed elsewhere," + echo " you should re-run configure with the --with-hackdir=DIR" + echo " option. For more information, run \`./configure --help'." + warning=yes +fi + +if test "$warning" != no; then + echo '' ; echo "$warnsep" ; echo '' +fi + +if test "$do_dir_warning" = no; then + if test "$warning" = no; then + echo '' + fi + echo "User programs will be installed in ${bindir}/" + echo "Screen savers will be installed in ${HACKDIR}/" + echo "Configuration dialogs will be installed in ${HACK_CONF_DIR}/" + echo "System-wide default settings will be installed in ${APPDEFAULTS}/" + echo '' +fi diff --git a/driver/.gdbinit b/driver/.gdbinit new file mode 100644 index 00000000..a585259f --- /dev/null +++ b/driver/.gdbinit @@ -0,0 +1,27 @@ +# If you're debugging xscreensaver and you are running a virtual root window +# manager, you'd better let the process handle these signals: it remaps the +# virtual root window when they arrive. If you don't do this, your window +# manager will be hosed. +# +# Also, gdb copes badly with breakpoints in functions that are called on the +# other side of a fork(). The Trace/BPT traps cause the spawned process to +# die. +# +#handle 1 pass nostop +#handle 3 pass nostop +#handle 4 pass nostop +#handle 6 pass nostop +#handle 7 pass nostop +#handle 8 pass nostop +#handle 9 pass nostop +#handle 10 pass nostop +#handle 11 pass nostop +#handle 12 pass nostop +#handle 13 pass nostop +#handle 15 pass nostop +#handle 19 pass nostop +set env MallocGuardEdges 1 +set env MallocPreScribble 1 +set env MallocScribble 1 +b exit +set args -debug diff --git a/driver/Makefile.in b/driver/Makefile.in new file mode 100644 index 00000000..af077ca9 --- /dev/null +++ b/driver/Makefile.in @@ -0,0 +1,1025 @@ +# driver/Makefile.in --- xscreensaver, Copyright (c) 1997-2010 Jamie Zawinski. +# the `../configure' script generates `driver/Makefile' from this file. + +@SET_MAKE@ +.SUFFIXES: +.SUFFIXES: .c .m .o + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = .. + +install_prefix = +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = $(datadir)/locale +mandir = @mandir@ +libexecdir = @libexecdir@ +mansuffix = 1 +manNdir = $(mandir)/man$(mansuffix) + +INTLTOOL_MERGE = @INTLTOOL_MERGE@ + +GTK_DATADIR = @GTK_DATADIR@ +GTK_APPDIR = $(GTK_DATADIR)/applications +GTK_ICONDIR = $(GTK_DATADIR)/pixmaps +GTK_GLADEDIR = $(GTK_DATADIR)/xscreensaver/glade +HACK_CONF_DIR = @HACK_CONF_DIR@ + +CC = @CC@ +OBJCC = @OBJCC@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +DEFS = @DEFS@ +INTL_DEFS = -DLOCALEDIR=\"$(localedir)\" +SUBP_DEFS = $(DEFS) -DDEFAULT_PATH_PREFIX='"@HACKDIR@"' +GTK_DEFS = $(DEFS) -DDEFAULT_ICONDIR='"$(GTK_GLADEDIR)"' +CONF_DEFS = -DHACK_CONFIGURATION_PATH='"$(HACK_CONF_DIR)"' + +LIBS = @LIBS@ +INTL_LIBS = @INTLLIBS@ +JPEG_LIBS = @JPEG_LIBS@ +PERL = @PERL@ + +DEPEND = @DEPEND@ +DEPEND_FLAGS = @DEPEND_FLAGS@ +DEPEND_DEFINES = @DEPEND_DEFINES@ + +SHELL = /bin/sh +INSTALL = @INSTALL@ +SUID_FLAGS = -o root -m 4755 +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_SETUID = @INSTALL_SETUID@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_DIRS = @INSTALL_DIRS@ + +X_CFLAGS = @X_CFLAGS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +XMU_LIBS = @XMU_LIBS@ +XPM_LIBS = @XPM_LIBS@ + +# Note: +# +# X_LIBS would more properly be called X_LDFLAGS (it contains the -L args.) +# X_PRE_LIBS contains extra libraries you have to link against on some systems, +# and that must come before -lX11. (e.g., -lSM and -lICE.) +# X_EXTRA_LIBS contains extra libraries needed by X that aren't a part of X. +# (e.g., -lsocket, -lnsl, etc.) +# +# I think (but am not totally sure) that LIBS is also really "LDFLAGS". +# +# SAVER_LIBS is the link line for "xscreensaver", and +# CMD_LIBS is the link line for "xscreensaver-command". +# GETIMG_LIBS is the link line for "xscreensaver-getimage". + + +AD_DIR = @APPDEFAULTS@ +PAM_DIR = /etc/pam.d +PAM_CONF = /etc/pam.conf + +UTILS_SRC = $(srcdir)/../utils +UTILS_BIN = ../utils + +INCLUDES_1 = -I. -I$(srcdir) -I$(UTILS_SRC) -I.. +INCLUDES = $(INCLUDES_1) @INCLUDES@ + +MOTIF_SRCS = demo-Xm.c demo-Xm-widgets.c +MOTIF_OBJS = demo-Xm.o demo-Xm-widgets.o + +GTK_SRCS = demo-Gtk.c demo-Gtk-conf.c \ + demo-Gtk-widgets.c demo-Gtk-support.c +GTK_EXTRA_OBJS = demo-Gtk-widgets.o demo-Gtk-support.o +GTK_OBJS = demo-Gtk.o demo-Gtk-conf.o @GTK_EXTRA_OBJS@ + +PWENT_SRCS = passwd-pwent.c +PWENT_OBJS = passwd-pwent.o + +KERBEROS_SRCS = passwd-kerberos.c +KERBEROS_OBJS = passwd-kerberos.o + +PAM_SRCS = passwd-pam.c +PAM_OBJS = passwd-pam.o + +PWHELPER_SRCS = passwd-helper.c +PWHELPER_OBJS = passwd-helper.o + +LOCK_SRCS_1 = lock.c passwd.c +LOCK_OBJS_1 = lock.o passwd.o +NOLOCK_SRCS_1 = lock.c +NOLOCK_OBJS_1 = lock.o + +TEST_SRCS = test-passwd.c test-uid.c test-xdpms.c test-grab.c \ + test-apm.c test-fade.c test-xinerama.c test-vp.c \ + test-randr.c xdpyinfo.c test-mlstring.c test-screens.c +TEST_EXES = test-passwd test-uid test-xdpms test-grab \ + test-apm test-fade test-xinerama test-vp \ + test-randr xdpyinfo test-mlstring test-screens + +MOTIF_LIBS = @MOTIF_LIBS@ @XPM_LIBS@ $(XMU_LIBS) +GTK_LIBS = @GTK_LIBS@ $(XMU_LIBS) +XML_LIBS = @XML_LIBS@ + +XDPMS_LIBS = @XDPMS_LIBS@ +XINERAMA_LIBS = @XINERAMA_LIBS@ +XINPUT_LIBS = @XINPUT_LIBS@ + +PASSWD_SRCS = @PASSWD_SRCS@ +PASSWD_OBJS = @PASSWD_OBJS@ +PASSWD_LIBS = @PASSWD_LIBS@ + +LOCK_SRCS = @LOCK_SRCS@ +LOCK_OBJS = @LOCK_OBJS@ + +XMU_SRCS = @XMU_SRCS@ +XMU_OBJS = @XMU_OBJS@ + +GL_SRCS = @SAVER_GL_SRCS@ +GL_OBJS = @SAVER_GL_OBJS@ +GL_LIBS = @SAVER_GL_LIBS@ + +ICON_SRC = $(UTILS_SRC)/images +LOGO = $(ICON_SRC)/logo-50.xpm +GTK_ICONS = $(ICON_SRC)/screensaver-*.png + +DEMO_UTIL_SRCS = $(UTILS_SRC)/resources.c $(UTILS_SRC)/usleep.c \ + $(UTILS_SRC)/visual.c $(XMU_SRCS) +DEMO_UTIL_OBJS = $(UTILS_BIN)/resources.o $(UTILS_BIN)/usleep.o \ + $(UTILS_BIN)/visual.o $(XMU_OBJS) + +SAVER_UTIL_SRCS = $(UTILS_SRC)/fade.c $(UTILS_SRC)/overlay.c \ + $(UTILS_SRC)/logo.c $(UTILS_SRC)/yarandom.c \ + $(UTILS_SRC)/minixpm.c \ + $(DEMO_UTIL_SRCS) +SAVER_UTIL_OBJS = $(UTILS_BIN)/fade.o $(UTILS_BIN)/overlay.o \ + $(UTILS_BIN)/logo.o $(UTILS_BIN)/yarandom.o \ + $(UTILS_BIN)/minixpm.o \ + $(DEMO_UTIL_OBJS) + +GETIMG_SRCS_1 = xscreensaver-getimage.c +GETIMG_OBJS_1 = xscreensaver-getimage.o + +GETIMG_SRCS = $(GETIMG_SRCS_1) \ + $(UTILS_BIN)/colorbars.o $(UTILS_BIN)/resources.o \ + $(UTILS_BIN)/yarandom.o $(UTILS_BIN)/visual.o \ + $(UTILS_BIN)/usleep.o $(UTILS_BIN)/hsv.o \ + $(UTILS_BIN)/colors.o $(UTILS_BIN)/grabscreen.o \ + $(UTILS_BIN)/logo.o $(UTILS_BIN)/minixpm.o prefs.o \ + $(XMU_SRCS) + +GETIMG_OBJS = $(GETIMG_OBJS_1) \ + $(UTILS_BIN)/colorbars.o $(UTILS_BIN)/resources.o \ + $(UTILS_BIN)/yarandom.o $(UTILS_BIN)/visual.o \ + $(UTILS_BIN)/usleep.o $(UTILS_BIN)/hsv.o \ + $(UTILS_BIN)/colors.o $(UTILS_BIN)/grabscreen.o \ + $(UTILS_BIN)/logo.o $(UTILS_BIN)/minixpm.o prefs.o \ + $(XMU_OBJS) + +SAVER_SRCS_1 = xscreensaver.c windows.c screens.c timers.c subprocs.c \ + exec.c xset.c splash.c setuid.c stderr.c mlstring.c +SAVER_OBJS_1 = xscreensaver.o windows.o screens.o timers.o subprocs.o \ + exec.o xset.o splash.o setuid.o stderr.o mlstring.o + +SAVER_SRCS = $(SAVER_SRCS_1) prefs.c dpms.c $(LOCK_SRCS) \ + $(SAVER_UTIL_SRCS) $(GL_SRCS) +SAVER_OBJS = $(SAVER_OBJS_1) prefs.o dpms.o $(LOCK_OBJS) \ + $(SAVER_UTIL_OBJS) $(GL_OBJS) + +CMD_SRCS = remote.c xscreensaver-command.c +CMD_OBJS = remote.o xscreensaver-command.o + +DEMO_SRCS_1 = prefs.c dpms.c +DEMO_OBJS_1 = prefs.o dpms.o + +DEMO_SRCS = $(DEMO_SRCS_1) remote.c exec.c $(DEMO_UTIL_SRCS) +DEMO_OBJS = $(DEMO_OBJS_1) remote.o exec.o $(DEMO_UTIL_OBJS) + +PDF2JPEG_SRCS = pdf2jpeg.m +PDF2JPEG_OBJS = pdf2jpeg.o +PDF2JPEG_LIBS = -framework Cocoa + +SAVER_LIBS = $(LIBS) $(X_LIBS) $(XMU_LIBS) @SAVER_LIBS@ \ + $(XDPMS_LIBS) $(XINERAMA_LIBS) $(GL_LIBS) $(X_PRE_LIBS) \ + -lXt -lX11 -lXext $(X_EXTRA_LIBS) \ + $(PASSWD_LIBS) + +CMD_LIBS = $(LIBS) $(X_LIBS) \ + $(X_PRE_LIBS) -lX11 -lXext $(X_EXTRA_LIBS) + +GETIMG_LIBS = $(LIBS) $(X_LIBS) $(XPM_LIBS) $(JPEG_LIBS) \ + $(X_PRE_LIBS) -lXt -lX11 $(XMU_LIBS) -lXext $(X_EXTRA_LIBS) + +EXES = xscreensaver xscreensaver-command xscreensaver-demo \ + xscreensaver-getimage @EXES_OSX@ +EXES2 = @ALL_DEMO_PROGRAMS@ +EXES_OSX = pdf2jpeg + +SCRIPTS_1 = xscreensaver-getimage-file xscreensaver-getimage-video \ + xscreensaver-text +SCRIPTS_OSX = xscreensaver-getimage-desktop +SCRIPTS = $(SCRIPTS_1) @SCRIPTS_OSX@ + +HDRS = XScreenSaver_ad.h XScreenSaver_Xm_ad.h \ + xscreensaver.h prefs.h remote.h exec.h \ + demo-Gtk-widgets.h demo-Gtk-stubs.h demo-Gtk-support.h \ + demo-Gtk-conf.h auth.h mlstring.h types.h +MEN_1 = xscreensaver.man xscreensaver-demo.man \ + xscreensaver-command.man \ + xscreensaver-text.man \ + xscreensaver-getimage.man \ + xscreensaver-getimage-file.man \ + xscreensaver-getimage-video.man +MEN_OSX = xscreensaver-getimage-desktop.man pdf2jpeg.man +MEN = $(MEN_1) @MEN_OSX@ + +EXTRAS = README Makefile.in \ + XScreenSaver.ad.in XScreenSaver-Xm.ad xscreensaver.pam.in \ + xscreensaver-demo.glade2 xscreensaver-demo.glade2p \ + screensaver-properties.desktop.in \ + .gdbinit +VMSFILES = compile_axp.com compile_decc.com link_axp.com link_decc.com \ + vms-getpwnam.c vms-pwd.h vms-hpwd.c vms-validate.c \ + vms_axp.opt vms_axp_12.opt vms_decc.opt vms_decc_12.opt + +TARFILES = $(EXTRAS) $(VMSFILES) $(SAVER_SRCS_1) \ + $(MOTIF_SRCS) $(GTK_SRCS) $(PWENT_SRCS) $(PWHELPER_SRCS) \ + $(KERBEROS_SRCS) $(PAM_SRCS) $(LOCK_SRCS_1) $(DEMO_SRCS_1) \ + $(CMD_SRCS) $(GETIMG_SRCS_1) $(PDF2JPEG_SRCS) $(HDRS) \ + $(SCRIPTS_1) $(SCRIPTS_OSX) $(MEN_1) $(MEN_OSX) \ + $(TEST_SRCS) + + +default: $(EXES) +all: $(EXES) $(EXES2) +tests: $(TEST_EXES) + +install: install-program install-ad install-scripts \ + install-gnome install-man install-xml install-pam +uninstall: uninstall-program uninstall-ad \ + uninstall-gnome uninstall-man uninstall-xml + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \ + install + +install-program: $(EXES) + @if [ ! -d $(install_prefix)$(bindir) ]; then \ + $(INSTALL_DIRS) $(install_prefix)$(bindir) ; \ + fi + @inst="$(INSTALL_PROGRAM)" ; \ + if [ @NEED_SETUID@ = yes ]; then \ + me=`PATH="$$PATH:/usr/ucb" whoami` ; \ + if [ "$$me" = root ]; then \ + inst="$(INSTALL_SETUID)" ; \ + else \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: xscreensaver has been compiled with support for shadow" ;\ + $$e " passwords. If your system actually uses shadow passwords," ;\ + $$e " then xscreensaver must be installed as a setuid root" ;\ + $$e " program in order for locking to work. To do this, you" ;\ + $$e " must run 'make install' as 'root', not as '$$me'." ;\ + $$e "" ;\ + $$e " For now, xscreensaver will be installed non-setuid, which" ;\ + $$e " means that locking might not work. (Try it and see.)" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + fi ; \ + fi ; \ + echo $$inst xscreensaver $(install_prefix)$(bindir)/xscreensaver ; \ + $$inst xscreensaver $(install_prefix)$(bindir)/xscreensaver + @for exe in xscreensaver-command xscreensaver-demo \ + xscreensaver-getimage @EXES_OSX@ ; do \ + echo $(INSTALL_PROGRAM) $$exe $(install_prefix)$(bindir)/$$exe ; \ + $(INSTALL_PROGRAM) $$exe $(install_prefix)$(bindir)/$$exe ; \ + done + +install-ad: XScreenSaver.ad + @if [ ! -d $(install_prefix)$(AD_DIR) ]; then \ + $(INSTALL_DIRS) $(install_prefix)$(AD_DIR) ; \ + fi + @-echo $(INSTALL_DATA) XScreenSaver.ad \ + $(install_prefix)$(AD_DIR)/XScreenSaver ; \ + if $(INSTALL_DATA) XScreenSaver.ad \ + $(install_prefix)$(AD_DIR)/XScreenSaver ; then \ + true ; \ + else \ + e=echo ; \ + if [ -f $(install_prefix)$(AD_DIR)/XScreenSaver ]; then \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: unable to install $(install_prefix)$(AD_DIR)/XScreenSaver" ;\ + $$e " That file exists, and is unwritable. It is probably from" ;\ + $$e " an older version of xscreensaver, and could cause things" ;\ + $$e " to malfunction. Please delete it!" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + exit 1 ; \ + else \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: unable to install $(install_prefix)$(AD_DIR)/XScreenSaver" ;\ + $$e " The directory is unwritable. This is probably ok;" ;\ + $$e " xscreensaver should work without that file." ;\ + $$e " ####################################################################";\ + $$e "" ;\ + exit 0 ; \ + fi \ + fi + +install-scripts: $(SCRIPTS) munge-scripts + @for program in $(SCRIPTS); do \ + if [ -r $$program ] ; then \ + p=$$program ; \ + else \ + p=$(srcdir)/$$program ; \ + fi ; \ + echo $(INSTALL_SCRIPT) $$p \ + $(install_prefix)$(bindir)/$$program ; \ + $(INSTALL_SCRIPT) $$p \ + $(install_prefix)$(bindir)/$$program ; \ + done + +munge-scripts: $(SCRIPTS) + @tmp=/tmp/mf.$$$$ ; \ + perl="${PERL}" ; \ + rm -f $$tmp ; \ + for program in $(SCRIPTS); do \ + sed "s@^\(#!\)\(/[^ ]*/perl[^ ]*\)\(.*\)\$$@\1$$perl\3@" \ + < $(srcdir)/$$program > $$tmp ; \ + if cmp -s $(srcdir)/$$program $$tmp ; then \ + true ; \ + else \ + echo "$$program: setting interpreter to $$perl" >&2 ; \ + cat $$tmp > ./$$program ; \ + fi ; \ + done ; \ + rm -f $$tmp + +# When installing man pages, we install "foo.man" as "foo.N" and update +# the .TH line in the installed file with one like +# +# .TH XScreenSaver N "V.VV (DD-MMM-YYYY)" "X Version 11" +# +# where N is the manual section suffix. +# +install-man: $(MEN) + @men="$(MEN)" ; \ + U=$(UTILS_SRC)/version.h ; \ + V=`sed -n 's/.*xscreensaver \([0-9]\.[^)]*)\).*/\1/p' < $$U` ; \ + T=/tmp/xs$$$$.$(mansuffix) ; \ + TH=".TH XScreenSaver $(mansuffix) \"$$V\" \"X Version 11\"" ; \ + echo "installing man pages: $$TH" ; \ + \ + if [ ! -d $(install_prefix)$(manNdir) ]; then \ + $(INSTALL_DIRS) $(install_prefix)$(manNdir) ; \ + fi ; \ + \ + for man in $$men; do \ + instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ; \ + manbase=`echo $$man | sed 's/\.man$$//'` ; \ + TH=".TH $$manbase $(mansuffix) \"$$V\" \"X Version 11\" \"XScreenSaver manual\"" ; \ + sed -e "s/^\.TH.*/$$TH/" \ + -e 's/^\(\.BR xscr.*(\)[^()]\(.*\)/\1$(mansuffix)\2/' \ + -e 's@(MANSUFFIX)@($(mansuffix))@g' \ + < $(srcdir)/$$man > $$T ; \ + echo $(INSTALL_DATA) $(srcdir)/$$man \ + $(install_prefix)$(manNdir)/$$instname ; \ + $(INSTALL_DATA) $$T \ + $(install_prefix)$(manNdir)/$$instname ; \ + done ; \ + rm -f $$T + +uninstall-program: + @for program in $(EXES) $(SCRIPTS); do \ + echo rm -f $(install_prefix)$(bindir)/$$program ; \ + rm -f $(install_prefix)$(bindir)/$$program ; \ + done + +uninstall-ad: + rm -f $(install_prefix)$(AD_DIR)/XScreenSaver + +uninstall-man: + @men="$(MEN)" ; \ + for man in $$men; do \ + instname=`echo $$man | sed 's/\.man$$/\.$(mansuffix)/'` ; \ + echo rm -f $(install_prefix)$(manNdir)/$$instname* ; \ + rm -f $(install_prefix)$(manNdir)/$$instname* ; \ + done + +install-pam: xscreensaver.pam + @src="xscreensaver.pam" ; \ + dest=`sed -n 's/.*PAM_SERVICE_NAME[ ]*"\([^"]*\)".*$$/\1/p' \ + < ../config.h` ; \ + dir="$(install_prefix)$(PAM_DIR)" ; \ + conf="$(PAM_CONF)" ; \ + \ + if [ -d $$dir ] ; then \ + \ + if [ -f $$dir/xdm ]; then \ + src2=$$dir/xdm ; \ + elif [ -f $$dir/login ]; then \ + src2=$$dir/login ; \ + fi ; \ + \ + if [ -z "$$src2" ]; then \ + echo $(INSTALL_DATA) $$src $$dir/$$dest ; \ + $(INSTALL_DATA) $$src $$dir/$$dest ; \ + else \ + src="xscreensaver.pam.$$$$" ; \ + echo "grep '^#%\|^auth\|^@include' $$src2 > $$src" ; \ + grep '^#%\|^auth\|^@include' $$src2 > $$src ; \ + echo $(INSTALL_DATA) $$src $$dir/$$dest ; \ + $(INSTALL_DATA) $$src $$dir/$$dest ; \ + echo rm -f $$src ; \ + rm -f $$src ; \ + fi ; \ + \ + if [ ! -f $$dir/$$dest ]; then \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: xscreensaver has been compiled with support for Pluggable" ;\ + $$e " Authentication Modules (PAM). However, we were unable to" ;\ + $$e " install the file $$dir/$$dest. PAM is unlikely" ;\ + $$e " to work without this file (and old-style password" ;\ + $$e " authentication will be used instead, which may or may not" ;\ + $$e " work.)" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + fi ; \ + elif [ -f $$conf -a "x$$dest" != "x" ]; then \ + if ( grep $$dest $$conf >/dev/null ); then \ + echo "$$conf unchanged: already has an entry for $$dest" ; \ + else \ + src="pam.conf.$$$$" ; \ + echo "grep -v $$dest $$conf > $$src" ; \ + grep -v $$dest $$conf > $$src ; \ + extras=`sed -n "s/^login\(.*auth.*\)$$/$$dest\1/p" $$conf`; \ + echo "$$extras" >> $$src ; \ + if [ "x$$extras" = "x" ]; then \ + echo "Error: no login rules in $$conf?" >&2 ; \ + else \ + echo "adding $$dest rules to $$src:" ; \ + echo "$$extras" | sed 's/^/ /' ; \ + fi ; \ + echo $(INSTALL_DATA) $$src $$conf ; \ + $(INSTALL_DATA) $$src $$conf ; \ + echo rm -f $$src ; \ + rm -f $$src ; \ + fi ; \ + if ( grep $$dest $$conf >/dev/null ); then \ + echo ; \ + else \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: xscreensaver has been compiled with support for Pluggable" ;\ + $$e " Authentication Modules (PAM). However, we were unable to" ;\ + $$e " install xscreensaver rules in the file $$conf." ;\ + $$e " PAM is unlikely to work without this (and old-style" ;\ + $$e " password authentication will be used instead, which may" ;\ + $$e " or may not work.)" ;\ + $$e " ####################################################################";\ + $$e "" ;\ + fi ; \ + fi + +# screensaver-properties.desktop +# into /usr/share/applications/ +install-gnome:: screensaver-properties.desktop + @if [ "$(GTK_DATADIR)" != "" ]; then \ + if [ ! -d "$(install_prefix)$(GTK_APPDIR)" ]; then \ + echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_APPDIR)" ;\ + $(INSTALL_DIRS) "$(install_prefix)$(GTK_APPDIR)" ;\ + fi ;\ + name2=xscreensaver-properties.desktop ;\ + echo $(INSTALL_DATA) screensaver-properties.desktop \ + $(install_prefix)$(GTK_APPDIR)/$$name2 ;\ + $(INSTALL_DATA) screensaver-properties.desktop \ + $(install_prefix)$(GTK_APPDIR)/$$name2 ;\ + fi + + +# xscreensaver.xpm +# into /usr/share/pixmaps/ +install-gnome:: $(LOGO) + @if [ "$(GTK_DATADIR)" != "" ]; then \ + if [ ! -d "$(install_prefix)$(GTK_ICONDIR)" ]; then \ + echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_ICONDIR)" ;\ + $(INSTALL_DIRS) "$(install_prefix)$(GTK_ICONDIR)" ;\ + fi ;\ + target=xscreensaver.xpm ;\ + echo $(INSTALL_DATA) $(LOGO) \ + $(install_prefix)$(GTK_ICONDIR)/$$target ;\ + $(INSTALL_DATA) $(LOGO) \ + $(install_prefix)$(GTK_ICONDIR)/$$target ;\ + fi + +# ../utils/images/screensaver-*.png +# into /usr/share/xscreensaver/glade/ +install-gnome:: + @if [ "$(GTK_DATADIR)" != "" ]; then \ + if [ ! -d "$(install_prefix)$(GTK_GLADEDIR)" ]; then \ + echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_GLADEDIR)" ;\ + $(INSTALL_DIRS) "$(install_prefix)$(GTK_GLADEDIR)" ;\ + fi ;\ + for target in $(GTK_ICONS) ; do \ + dest=`echo $$target | sed 's@^.*/@@'` ;\ + echo $(INSTALL_DATA) $$target \ + $(install_prefix)$(GTK_GLADEDIR)/$$dest ;\ + $(INSTALL_DATA) $$target \ + $(install_prefix)$(GTK_GLADEDIR)/$$dest ;\ + done ;\ + fi + +# xscreensaver-demo.glade2 +# into /usr/share/xscreensaver/glade/ +install-gnome:: xscreensaver-demo.glade2 + @if [ "$(GTK_DATADIR)" != "" ]; then \ + if [ ! -d "$(install_prefix)$(GTK_GLADEDIR)" ]; then \ + echo $(INSTALL_DIRS) "$(install_prefix)$(GTK_GLADEDIR)" ;\ + $(INSTALL_DIRS) "$(install_prefix)$(GTK_GLADEDIR)" ;\ + fi ;\ + target=xscreensaver-demo.glade2 ;\ + echo $(INSTALL_DATA) $(srcdir)/$$target \ + $(install_prefix)$(GTK_GLADEDIR)/$$target ;\ + if $(INSTALL_DATA) $(srcdir)/$$target \ + $(install_prefix)$(GTK_GLADEDIR)/$$target ;\ + then true ;\ + else \ + e=echo ; \ + $$e "" ;\ + $$e " ####################################################################";\ + $$e " Warning: unable to install $$target into" ;\ + $$e " $(install_prefix)$(GTK_GLADEDIR)/." ;\ + $$e " Without this file, xscreensaver-demo will not" ;\ + $$e " be able to run properly." ;\ + $$e " ####################################################################";\ + $$e "" ;\ + exit 1 ; \ + fi ; \ + fi + + +# screensaver-properties.desktop +# into /usr/share/applications/ +uninstall-gnome:: + @if [ "$(GTK_DATADIR)" != "" ]; then \ + f=xscreensaver-properties.desktop ;\ + echo rm -f $(install_prefix)$(GTK_APPDIR)/$$f ;\ + rm -f $(install_prefix)$(GTK_APPDIR)/$$f ;\ + fi + +# xscreensaver.xpm +# into /usr/share/pixmaps/ +uninstall-gnome:: + @if [ "$(GTK_ICONDIR)" != "" ]; then \ + target=xscreensaver.xpm ;\ + echo rm -f $(install_prefix)$(GTK_ICONDIR)/$$target ;\ + rm -f $(install_prefix)$(GTK_ICONDIR)/$$target ;\ + fi + +# ../utils/images/screensaver-*.png +# into /usr/share/xscreensaver/glade/ +uninstall-gnome:: + @if [ "$(GTK_DATADIR)" != "" ]; then \ + for target in $(GTK_ICONS) ; do \ + dest=`echo $$target | sed 's@^.*/@@'` ;\ + echo rm -f $(install_prefix)$(GTK_GLADEDIR)/$$dest ;\ + rm -f $(install_prefix)$(GTK_GLADEDIR)/$$dest ;\ + done ;\ + fi + +# xscreensaver-demo.glade2 +# into /usr/share/xscreensaver/glade/ +uninstall-gnome:: xscreensaver-demo.glade2 + @if [ "$(GTK_DATADIR)" != "" ]; then \ + target=xscreensaver-demo.glade2 ;\ + echo rm -f $(install_prefix)$(GTK_GLADEDIR)/$$target ;\ + rm -f $(install_prefix)$(GTK_GLADEDIR)/$$target ;\ + fi + +# /usr/share/xscreensaver/config/README +install-xml: + @dest=$(install_prefix)$(HACK_CONF_DIR) ; \ + if [ ! -d $$dest ]; then \ + $(INSTALL_DIRS) $$dest ; \ + fi ; \ + src=$(srcdir)/../hacks/config ; \ + echo $(INSTALL_DATA) $$src/README $$dest/README ; \ + $(INSTALL_DATA) $$src/README $$dest/README + + +# /usr/share/xscreensaver/config/README +uninstall-xml: + rm -f $(install_prefix)$(HACK_CONF_DIR)/README + +clean: + -rm -f *.o a.out core $(EXES) $(EXES2) $(TEST_EXES) \ + XScreenSaver_ad.h XScreenSaver_Xm_ad.h + +distclean: clean + -rm -f Makefile XScreenSaver.ad \ + TAGS *~ "#"* screensaver-properties.desktop + +# Adds all current dependencies to Makefile +depend: XScreenSaver_ad.h XScreenSaver_Xm_ad.h + $(DEPEND) -s '# DO NOT DELETE: updated by make depend' \ + $(DEPEND_FLAGS) -- \ + $(INCLUDES_1) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \ + $(SAVER_SRCS) $(CMD_SRCS) $(GETIMG_SRCS_1) + +# Adds some dependencies to Makefile.in -- not totally accurate, but pretty +# close. This excludes dependencies on files in /usr/include, etc. It tries +# to include only dependencies on files which are themselves a part of this +# package. +distdepend: check_men update_ad_version XScreenSaver_ad.h XScreenSaver_Xm_ad.h + @echo updating dependencies in `pwd`/Makefile.in... ; \ + $(DEPEND) -w 0 -f - \ + -s '# DO NOT DELETE: updated by make distdepend' $(DEPEND_FLAGS) -- \ + $(INCLUDES_1) $(DEFS) $(DEPEND_DEFINES) $(CFLAGS) $(X_CFLAGS) -- \ + $(SAVER_SRCS_1) $(MOTIF_SRCS) $(GTK_SRCS) $(GETIMG_SRCS_1) \ + $(PWENT_SRCS) $(LOCK_SRCS_1) $(DEMO_SRCS_1) $(CMD_SRCS) \ + $(TEST_SRCS) 2>/dev/null | \ + sort -d | \ + ( \ + awk '/^# .*Makefile.in ---/,/^# DO .*distdepend/' < Makefile.in ; \ + sed -e '/^#.*/d' \ + -e 's@ \./@ @g;s@ /[^ ]*@@g;/^.*:$$/d' \ + -e 's@\.\./utils@$$(UTILS_SRC)@g' \ + -e 's@ \([^$$]\)@ $$(srcdir)/\1@g' \ + -e 's@$$.*\(XScreenSaver_ad\)@\1@g' \ + -e 's@$$.*\(XScreenSaver_Xm_ad\)@\1@g' \ + -e 's@ $$(srcdir)/\(.*config\.h\)@ \1@g' ; \ + echo '' \ + ) > /tmp/distdepend.$$$$ && \ + mv Makefile.in Makefile.in.bak && \ + mv /tmp/distdepend.$$$$ Makefile.in + +# Updates the version number in the app-defaults file to be in sync with +# the version number in version.h. This is so people can tell when they +# have a version skew between the app-defaults file and the executable. +# Also update hacks/config/README in the same way. +update_ad_version:: + @ \ + files="XScreenSaver.ad.in ../hacks/config/README ../OSX/bindist.rtf" ; \ + U=$(UTILS_SRC)/version.h ; \ + V=`sed -n 's/[^0-9]*\([0-9]\.[0-9][^. ]*\).*/\1/p' < $$U` ; \ + Y=`date '+%Y'` ; \ + D=`date '+%d-%b-%Y'` ; \ + for S in $$files ; do \ + T=/tmp/xs.$$$$ ; \ + sed -e "s/\(.*version \)[0-9][0-9]*\.[0-9]*[ab]*[0-9]*\(.*\)/\1$$V\2/" \ + -e "s/\([0-9][0-9]-[A-Z][a-z][a-z]-[0-9][0-9][0-9]*\)/$$D/" \ + -e "s/\( [0-9][0-9][0-9][0-9]-\)[0-9][0-9][0-9][0-9] /\1$$Y /" \ + < $$S > $$T ; \ + if cmp -s $$S $$T ; then \ + true ; \ + else \ + cat $$T > $$S ; \ + echo "updated $$S to $$V $$D" ; \ + fi ; \ + done ; \ + rm $$T + +TAGS: tags +tags: + find $(srcdir) -name '*.[chly]' -print | xargs etags -a + +echo_tarfiles: + @$(MAKE) XScreenSaver_ad.h XScreenSaver_Xm_ad.h 2>&1 >/dev/null + @echo $(TARFILES) + +check_men: + @badmen="" ; \ + for exe in $(EXES); do \ + if ! [ -f $(srcdir)/$$exe.man ]; then \ + badmen="$$badmen $$exe" ; \ + fi ; \ + done ; \ + if [ -n "$$badmen" ]; then \ + echo "" ; \ + echo "Warning: The following programs have no manuals:" ; \ + echo "" ; \ + for m in $$badmen ; do \ + echo " $$m" ; \ + done ; \ + echo "" ; \ + fi + + +# Rules for noticing when the objects from the utils directory are out of +# date with respect to their sources, and going and building them according +# to the rules in their own Makefile... +# +$(UTILS_BIN)/fade.o: $(UTILS_SRC)/fade.c +$(UTILS_BIN)/overlay.o: $(UTILS_SRC)/overlay.c +$(UTILS_BIN)/resources.o: $(UTILS_SRC)/resources.c +$(UTILS_BIN)/usleep.o: $(UTILS_SRC)/usleep.c +$(UTILS_BIN)/visual.o: $(UTILS_SRC)/visual.c +$(UTILS_BIN)/xmu.o: $(UTILS_SRC)/xmu.c +$(UTILS_BIN)/logo.o: $(UTILS_SRC)/logo.c +$(UTILS_BIN)/minixpm.o: $(UTILS_SRC)/minixpm.c +$(UTILS_BIN)/yarandom.o: $(UTILS_SRC)/yarandom.c +$(UTILS_BIN)/colorbars.o: $(UTILS_SRC)/colorbars.c + +$(SAVER_UTIL_OBJS): + $(MAKE) -C $(UTILS_BIN) $(@F) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" + +# How we build object files in this directory. +.c.o: + $(CC) -c $(INCLUDES) $(DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) $< + +.m.o: + $(OBJCC) -c $(INCLUDES) $(DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) $< + +# subprocs takes an extra -D option. +subprocs.o: subprocs.c + $(CC) -c $(INCLUDES) $(SUBP_DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) \ + $(srcdir)/subprocs.c + +# xscreensaver takes an extra -D option. +xscreensaver.o: xscreensaver.c + $(CC) -c $(INCLUDES) $(DEFS) $(INTL_DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) \ + $(srcdir)/xscreensaver.c + +# demo-Gtk takes extra -D options, and an extra -I option. +demo-Gtk.o: demo-Gtk.c + $(CC) -c $(INCLUDES) $(SUBP_DEFS) -I$(ICON_SRC) \ + $(GTK_DEFS) $(INTL_DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) \ + $(srcdir)/demo-Gtk.c + +# demo-Gtk-conf takes an extra -D option. +demo-Gtk-conf.o: demo-Gtk-conf.c + $(CC) -c $(INCLUDES) $(CONF_DEFS) $(GTK_DEFS) $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) \ + $(srcdir)/demo-Gtk-conf.c + + +# How we build the default app-defaults file into the program. +# +XScreenSaver_ad.h: XScreenSaver.ad + $(SHELL) $(UTILS_SRC)/ad2c XScreenSaver.ad > XScreenSaver_ad.h + +XScreenSaver_Xm_ad.h: XScreenSaver-Xm.ad + $(SHELL) $(UTILS_SRC)/ad2c XScreenSaver-Xm.ad > XScreenSaver_Xm_ad.h + +@INTLTOOL_DESKTOP_RULE@ + +# The executables linked in this directory. +# +xscreensaver: $(SAVER_OBJS) + $(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(SAVER_LIBS) + +xscreensaver-command: $(CMD_OBJS) + $(CC) $(LDFLAGS) -o $@ $(CMD_OBJS) $(CMD_LIBS) + + +xscreensaver-demo: @PREFERRED_DEMO_PROGRAM@ + @if [ "@PREFERRED_DEMO_PROGRAM@" = "" ]; then \ + echo "WARNING: neither GTK nor Motif are available," \ + "therefore no xscreensaver-demo!" ; \ + rm -f $@@EXEEXT@ ; \ + else \ + echo cp -p @PREFERRED_DEMO_PROGRAM@@EXEEXT@ $@@EXEEXT@ ; \ + cp -p @PREFERRED_DEMO_PROGRAM@@EXEEXT@ $@@EXEEXT@ ; \ + fi + +xscreensaver-demo-Xm: $(DEMO_OBJS) $(MOTIF_OBJS) + $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(MOTIF_OBJS) $(LIBS) $(X_LIBS) \ + $(MOTIF_LIBS) $(INTL_LIBS) $(X_PRE_LIBS) -lXt -lX11 \ + $(XDPMS_LIBS) $(XINERAMA_LIBS) -lXext $(X_EXTRA_LIBS) + +xscreensaver-demo-Gtk: $(DEMO_OBJS) $(GTK_OBJS) + $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(GTK_OBJS) $(LIBS) $(X_LIBS) \ + $(GTK_LIBS) $(XPM_LIBS) $(XML_LIBS) $(INTL_LIBS) $(X_PRE_LIBS) \ + -lXt -lX11 $(XDPMS_LIBS) $(XINERAMA_LIBS) -lXext $(X_EXTRA_LIBS) + +demo-Gtk.o: XScreenSaver_ad.h +demo-Xm.o: XScreenSaver_Xm_ad.h +xscreensaver.o: XScreenSaver_ad.h +xscreensaver-getimage.o: XScreenSaver_ad.h + +xscreensaver-getimage: $(GETIMG_OBJS) + $(CC) $(LDFLAGS) -o $@ $(GETIMG_OBJS) $(GETIMG_LIBS) -lm + +pdf2jpeg: $(PDF2JPEG_OBJS) + $(OBJCC) $(LDFLAGS) -o $@ $(PDF2JPEG_OBJS) $(PDF2JPEG_LIBS) -lm + + +TEST_PASSWD_OBJS = test-passwd.o $(LOCK_OBJS_1) $(PASSWD_OBJS) \ + subprocs.o setuid.o splash.o prefs.o mlstring.o exec.o \ + $(SAVER_UTIL_OBJS) +test-passwd.o: XScreenSaver_ad.h + +test-passwd: $(TEST_PASSWD_OBJS) XScreenSaver_ad.h + $(CC) $(LDFLAGS) -o $@ $(TEST_PASSWD_OBJS) $(SAVER_LIBS) + +test-uid: test-uid.o + $(CC) $(LDFLAGS) -o $@ test-uid.o + +test-xdpms: test-xdpms.o + $(CC) $(LDFLAGS) -o $@ test-xdpms.o $(LIBS) $(X_LIBS) $(XDPMS_LIBS) \ + $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +test-xinerama: test-xinerama.o + $(CC) $(LDFLAGS) -o $@ test-xinerama.o $(LIBS) $(X_LIBS) $(SAVER_LIBS) \ + $(X_PRE_LIBS) $(XINERAMA_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +test-vp: test-vp.o + $(CC) $(LDFLAGS) -o $@ test-vp.o $(LIBS) $(X_LIBS) $(SAVER_LIBS) \ + $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +test-randr: test-randr.o + $(CC) $(LDFLAGS) -o $@ test-randr.o $(LIBS) $(X_LIBS) $(SAVER_LIBS) \ + $(X_PRE_LIBS) -lXt -lX11 -lXext $(X_EXTRA_LIBS) + +test-grab: test-grab.o + $(CC) $(LDFLAGS) -o $@ test-grab.o $(SAVER_LIBS) + +test-apm: test-apm.o + $(CC) $(LDFLAGS) -o $@ test-apm.o $(SAVER_LIBS) -lapm + +test-mlstring.o: mlstring.c +test-mlstring: test-mlstring.o + $(CC) -DTEST $(LDFLAGS) -o $@ test-mlstring.o $(SAVER_LIBS) + +TEST_FADE_OBJS = test-fade.o $(UTILS_SRC)/fade.o $(DEMO_UTIL_OBJS) +test-fade: test-fade.o $(UTILS_BIN)/fade.o + $(CC) $(LDFLAGS) -o $@ $(TEST_FADE_OBJS) $(SAVER_LIBS) + +TEST_SCREENS_OBJS = test-screens.o $(DEMO_UTIL_OBJS) +test-screens.o: screens.c +test-screens: test-screens.o + $(CC) $(LDFLAGS) -o $@ $(TEST_SCREENS_OBJS) $(SAVER_LIBS) + + +xdpyinfo.o: xdpyinfo.c + $(CC) -c $(INCLUDES) -DHAVE_GLX $(CPPFLAGS) $(CFLAGS) $(X_CFLAGS) \ + $(srcdir)/xdpyinfo.c + +xdpyinfo: xdpyinfo.o + $(CC) $(LDFLAGS) -o $@ xdpyinfo.o \ + $(LIBS) $(X_LIBS) @GL_LIBS@ \ + $(X_PRE_LIBS) -lX11 -lXext $(X_EXTRA_LIBS) -lm + + +############################################################################## +# +# DO NOT DELETE: updated by make distdepend + +demo-Gtk-conf.o: ../config.h +demo-Gtk-conf.o: $(srcdir)/demo-Gtk-conf.h +demo-Gtk-conf.o: $(UTILS_SRC)/xscreensaver-intl.h +demo-Gtk.o: XScreenSaver_ad.h +demo-Gtk.o: ../config.h +demo-Gtk.o: $(srcdir)/demo-Gtk-conf.h +demo-Gtk.o: $(srcdir)/demo-Gtk-support.h +demo-Gtk.o: $(srcdir)/demo-Gtk-widgets.h +demo-Gtk.o: $(srcdir)/prefs.h +demo-Gtk.o: $(srcdir)/remote.h +demo-Gtk.o: $(srcdir)/types.h +demo-Gtk.o: $(UTILS_SRC)/resources.h +demo-Gtk.o: $(UTILS_SRC)/usleep.h +demo-Gtk.o: $(UTILS_SRC)/version.h +demo-Gtk.o: $(UTILS_SRC)/visual.h +demo-Gtk.o: $(UTILS_SRC)/xscreensaver-intl.h +demo-Gtk-support.o: ../config.h +demo-Gtk-support.o: $(srcdir)/demo-Gtk-support.h +demo-Gtk-widgets.o: ../config.h +demo-Gtk-widgets.o: $(srcdir)/demo-Gtk-stubs.h +demo-Gtk-widgets.o: $(srcdir)/demo-Gtk-support.h +demo-Gtk-widgets.o: $(srcdir)/demo-Gtk-widgets.h +demo-Xm.o: ../config.h +demo-Xm-widgets.o: ../config.h +dpms.o: ../config.h +dpms.o: $(srcdir)/prefs.h +dpms.o: $(srcdir)/types.h +dpms.o: $(srcdir)/xscreensaver.h +exec.o: ../config.h +exec.o: $(srcdir)/exec.h +lock.o: $(srcdir)/auth.h +lock.o: ../config.h +lock.o: $(srcdir)/mlstring.h +lock.o: $(srcdir)/prefs.h +lock.o: $(srcdir)/types.h +lock.o: $(UTILS_SRC)/resources.h +lock.o: $(srcdir)/xscreensaver.h +mlstring.o: $(srcdir)/mlstring.h +passwd.o: $(srcdir)/auth.h +passwd.o: ../config.h +passwd.o: $(srcdir)/prefs.h +passwd.o: $(srcdir)/types.h +passwd.o: $(srcdir)/xscreensaver.h +passwd-pwent.o: ../config.h +prefs.o: ../config.h +prefs.o: $(srcdir)/prefs.h +prefs.o: $(srcdir)/types.h +prefs.o: $(UTILS_SRC)/resources.h +prefs.o: $(UTILS_SRC)/version.h +remote.o: ../config.h +remote.o: $(srcdir)/remote.h +screens.o: ../config.h +screens.o: $(srcdir)/prefs.h +screens.o: $(srcdir)/types.h +screens.o: $(UTILS_SRC)/visual.h +screens.o: $(srcdir)/xscreensaver.h +setuid.o: ../config.h +setuid.o: $(srcdir)/prefs.h +setuid.o: $(srcdir)/types.h +setuid.o: $(srcdir)/xscreensaver.h +splash.o: ../config.h +splash.o: $(srcdir)/prefs.h +splash.o: $(srcdir)/types.h +splash.o: $(UTILS_SRC)/resources.h +splash.o: $(srcdir)/xscreensaver.h +stderr.o: ../config.h +stderr.o: $(srcdir)/prefs.h +stderr.o: $(srcdir)/types.h +stderr.o: $(UTILS_SRC)/resources.h +stderr.o: $(UTILS_SRC)/visual.h +stderr.o: $(srcdir)/xscreensaver.h +subprocs.o: ../config.h +subprocs.o: $(srcdir)/exec.h +subprocs.o: $(srcdir)/prefs.h +subprocs.o: $(srcdir)/types.h +subprocs.o: $(UTILS_SRC)/visual.h +subprocs.o: $(UTILS_SRC)/yarandom.h +subprocs.o: $(srcdir)/xscreensaver.h +test-apm.o: ../config.h +test-fade.o: ../config.h +test-fade.o: $(srcdir)/prefs.h +test-fade.o: $(srcdir)/types.h +test-fade.o: $(UTILS_SRC)/fade.h +test-fade.o: $(srcdir)/xscreensaver.h +test-grab.o: ../config.h +test-mlstring.o: $(srcdir)/mlstring.c +test-mlstring.o: $(srcdir)/mlstring.h +test-passwd.o: XScreenSaver_ad.h +test-passwd.o: $(srcdir)/auth.h +test-passwd.o: ../config.h +test-passwd.o: $(srcdir)/prefs.h +test-passwd.o: $(srcdir)/types.h +test-passwd.o: $(UTILS_SRC)/resources.h +test-passwd.o: $(UTILS_SRC)/version.h +test-passwd.o: $(UTILS_SRC)/visual.h +test-passwd.o: $(srcdir)/xscreensaver.h +test-randr.o: ../config.h +test-screens.o: ../config.h +test-screens.o: $(srcdir)/prefs.h +test-screens.o: $(srcdir)/screens.c +test-screens.o: $(srcdir)/types.h +test-screens.o: $(UTILS_SRC)/visual.h +test-screens.o: $(srcdir)/xscreensaver.h +test-uid.o: ../config.h +test-vp.o: ../config.h +test-xdpms.o: ../config.h +test-xinerama.o: ../config.h +timers.o: ../config.h +timers.o: $(srcdir)/prefs.h +timers.o: $(srcdir)/types.h +timers.o: $(srcdir)/xscreensaver.h +windows.o: ../config.h +windows.o: $(srcdir)/prefs.h +windows.o: $(srcdir)/types.h +windows.o: $(UTILS_SRC)/fade.h +windows.o: $(UTILS_SRC)/visual.h +windows.o: $(srcdir)/xscreensaver.h +xscreensaver-command.o: ../config.h +xscreensaver-command.o: $(srcdir)/remote.h +xscreensaver-command.o: $(UTILS_SRC)/version.h +xscreensaver-getimage.o: ../config.h +xscreensaver-getimage.o: XScreenSaver_ad.h +xscreensaver-getimage.o: $(srcdir)/prefs.h +xscreensaver-getimage.o: $(srcdir)/types.h +xscreensaver-getimage.o: $(UTILS_SRC)/colorbars.h +xscreensaver-getimage.o: $(UTILS_SRC)/grabscreen.h +xscreensaver-getimage.o: $(UTILS_SRC)/resources.h +xscreensaver-getimage.o: $(UTILS_SRC)/utils.h +xscreensaver-getimage.o: $(UTILS_SRC)/version.h +xscreensaver-getimage.o: $(UTILS_SRC)/visual.h +xscreensaver-getimage.o: $(UTILS_SRC)/vroot.h +xscreensaver-getimage.o: $(UTILS_SRC)/yarandom.h +xscreensaver.o: XScreenSaver_ad.h +xscreensaver.o: $(srcdir)/auth.h +xscreensaver.o: ../config.h +xscreensaver.o: $(srcdir)/prefs.h +xscreensaver.o: $(srcdir)/types.h +xscreensaver.o: $(UTILS_SRC)/resources.h +xscreensaver.o: $(UTILS_SRC)/usleep.h +xscreensaver.o: $(UTILS_SRC)/version.h +xscreensaver.o: $(UTILS_SRC)/visual.h +xscreensaver.o: $(UTILS_SRC)/yarandom.h +xscreensaver.o: $(srcdir)/xscreensaver.h +xset.o: ../config.h +xset.o: $(srcdir)/prefs.h +xset.o: $(srcdir)/types.h +xset.o: $(srcdir)/xscreensaver.h + diff --git a/driver/README b/driver/README new file mode 100644 index 00000000..df64793b --- /dev/null +++ b/driver/README @@ -0,0 +1,6 @@ + +This directory contains the source for xscreensaver and xscreensaver-command, +the screensaver driver, and the program for externally controlling it. Some +stuff from the ../utils/ directory is used here as well. + +If you have compilation problems, check the parameters in ../config.h. diff --git a/driver/XScreenSaver-Xm.ad b/driver/XScreenSaver-Xm.ad new file mode 100644 index 00000000..6b04ae97 --- /dev/null +++ b/driver/XScreenSaver-Xm.ad @@ -0,0 +1,126 @@ +! Resources for the Motif dialog boxes of the "xscreensaver-demo" program. +! +*fontList: *-helvetica-medium-r-*-*-*-120-*-*-*-iso8859-1 +*demoDialog*label1.fontList: *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1 +*cmdText.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1 +*label0.fontList: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +XScreenSaver*doc.fontList: *-helvetica-medium-r-*-*-*-100-*-*-*-iso8859-1 +! above must be fully qualified to get around *sgiMode. + +*foreground: #000000 +*background: #C0C0C0 +*XmTextField.foreground: #000000 +*XmTextField.background: #FFFFFF +*list.foreground: #000000 +*list.background: #FFFFFF + +*ApplicationShell.title: XScreenSaver +*warning.title: XScreenSaver +*warning_popup.title: XScreenSaver +*allowShellResize: True +*autoUnmanage: False + +*menubar*file.labelString: File +*menubar*file.mnemonic: F +*file.blank.labelString: Blank Screen Now +*file.blank.mnemonic: B +*file.lock.labelString: Lock Screen Now +*file.lock.mnemonic: L +*file.kill.labelString: Kill Daemon +*file.kill.mnemonic: K +*file.restart.labelString: Restart Daemon +*file.restart.mnemonic: R +*file.exit.labelString: Exit +*file.exit.mnemonic: E + +*menubar*edit.labelString: Edit +*menubar*edit.mnemonic: E +*edit.cut.labelString: Cut +*edit.cut.mnemonic: u +*edit.copy.labelString: Copy +*edit.copy.mnemonic: C +*edit.paste.labelString: Paste +*edit.paste.mnemonic: P + +*menubar*help.labelString: Help +*menubar*help.mnemonic: H +*help.about.labelString: About... +*help.about.mnemonic: A +*help.docMenu.labelString: Documentation... +*help.docMenu.mnemonic: D + +*demoTab.marginWidth: 10 +*optionsTab.marginWidth: 10 + +*XmScrolledWindow.topOffset: 10 +*XmScrolledWindow.leftOffset: 10 +*demoTab.topOffset: 4 +*form1.bottomOffset: 10 +*form3.leftOffset: 10 +*form3.rightOffset: 10 +*frame.topOffset: 10 +*frame.bottomOffset: 10 +*enabled.topOffset: 10 +*visLabel.topOffset: 10 +*combo.topOffset: 10 +*form4.bottomOffset: 4 +*hr.bottomOffset: 4 +*XmComboBox.marginWidth: 0 +*XmComboBox.marginHeight: 0 + +*demo.marginWidth: 30 +*demo.marginHeight: 4 +*man.marginWidth: 10 +*man.marginHeight: 4 +*down.leftOffset: 40 +*down.marginWidth: 4 +*down.marginHeight: 4 +*up.marginWidth: 4 +*up.marginHeight: 4 +*frame.traversalOn: False + +*list.automaticSelection: True +*list.visibleItemCount: 20 +*doc.columns: 60 +*combo.columns: 11 + +*demoTab.labelString: Graphics Demos +*optionsTab.labelString: Screensaver Options +*down.labelString: \\/ +*up.labelString: /\\ +*frameLabel.labelString: +*cmdLabel.labelString: Command Line: +*cmdLabel.alignment: ALIGNMENT_BEGINNING +*enabled.labelString: Enabled +*visLabel.labelString: Visual: +*visLabel.alignment: ALIGNMENT_END +*visLabel.leftOffset: 20 +*demo.labelString: Demo +*man.labelString: Documentation... +*done.labelString: Quit + +*preferencesLabel.labelString: XScreenSaver Parameters + +*timeoutLabel.labelString: Saver Timeout +*cycleLabel.labelString: Cycle Timeout +*fadeSecondsLabel.labelString: Fade Duration +*fadeTicksLabel.labelString: Fade Ticks +*lockLabel.labelString: Lock Timeout +*passwdLabel.labelString: Password Timeout +*preferencesForm*XmTextField.columns: 8 + +*verboseToggle.labelString: Verbose +*cmapToggle.labelString: Install Colormap +*fadeToggle.labelString: Fade Colormap +*unfadeToggle.labelString: Unfade Colormap +*lockToggle.labelString: Require Password + + +*OK.marginWidth: 30 +*OK.marginHeight: 4 +*OK.leftOffset: 10 +*OK.bottomOffset: 10 +*Cancel.marginWidth: 30 +*Cancel.marginHeight: 4 +*Cancel.rightOffset: 10 +*Cancel.bottomOffset: 10 diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in new file mode 100644 index 00000000..aa92e347 --- /dev/null +++ b/driver/XScreenSaver.ad.in @@ -0,0 +1,509 @@ +! +! XScreenSaver +! +! a screen saver and locker for the X window system +! by Jamie Zawinski +! +! version 5.26 +! 09-Dec-2013 +! +! See "man xscreensaver" for more info. The latest version is always +! available at http://www.jwz.org/xscreensaver/ + + +! These resources, when placed in the system-wide app-defaults directory +! (e.g., /usr/lib/X11/app-defaults/XScreenSaver) will provide the default +! settings for new users. However, if you have a ".xscreensaver" file in +! your home directory, the settings in that file take precedence. + + +! Don't hand this file to "xrdb" -- that isn't how app-defaults files work. +! Though app-defaults files have (mostly) the same syntax as your ~/.Xdefaults +! file, they are used differently, and if you run this file through xrdb, +! you will probably mess things up. + +#error Do not run app-defaults files through xrdb! +#error That does not do what you might expect. +#error Put this file in /usr/lib/X11/app-defaults/XScreenSaver instead. + +! /* (xrdb prevention kludge: whole file) + +*mode: random +*timeout: 0:10:00 +*cycle: 0:10:00 +*lockTimeout: 0:00:00 +*passwdTimeout: 0:00:30 +*dpmsEnabled: False +*dpmsQuickoffEnabled: False +*dpmsStandby: 2:00:00 +*dpmsSuspend: 2:00:00 +*dpmsOff: 4:00:00 +*grabDesktopImages: True +*grabVideoFrames: False +*chooseRandomImages: @DEFAULT_IMAGES_P@ +! This can be a local directory name, or the URL of an RSS or Atom feed. +*imageDirectory: @DEFAULT_IMAGE_DIRECTORY@ +*nice: 10 +*memoryLimit: 0 +*lock: False +*verbose: False +*timestamp: True +*fade: True +*unfade: False +*fadeSeconds: 0:00:03 +*fadeTicks: 20 +*splash: True +*splashDuration: 0:00:05 +*visualID: default +*captureStderr: True +*ignoreUninstalledPrograms: False + +*textMode: file +*textLiteral: XScreenSaver +*textFile: @DEFAULT_TEXT_FILE@ +*textProgram: fortune +*textURL: http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss + +*overlayTextForeground: #FFFF00 +*overlayTextBackground: #000000 +*overlayStderr: True +*font: *-medium-r-*-140-*-m-* + +! The default is to use these extensions if available (as noted.) +*sgiSaverExtension: True +*xidleExtension: True +*procInterrupts: True + +! Turning this on makes pointerHysteresis not work. +*xinputExtensionDev: False + +! Set this to True if you are experiencing longstanding XFree86 bug #421 +! (xscreensaver not covering the whole screen) +GetViewPortIsFullOfLies: False + +! This is what the "Demo" button on the splash screen runs (/bin/sh syntax.) +*demoCommand: xscreensaver-demo + +! This is what the "Prefs" button on the splash screen runs (/bin/sh syntax.) +*prefsCommand: xscreensaver-demo -prefs + +! This is the URL loaded by the "Help" button on the splash screen, +! and by the "Documentation" menu item in xscreensaver-demo. +*helpURL: http://www.jwz.org/xscreensaver/man.html + +! loadURL -- how the "Help" buttons load the helpURL (/bin/sh syntax.) +! manualCommand -- how the "Documentation" buttons display man pages. +! +! And there are so very many options to choose from! +! +! Gnome 2.4, 2.6: (yelp can't display man pages, as of 2.6.3) +! +@GNOME24@*loadURL: @WITH_BROWSER@ '%s' +@GNOME24@*manualCommand: gnome-terminal --title '%s manual' \ +@GNOME24@ --command '/bin/sh -c "man %s; read foo"' +! +! Gnome 2.2: +! +@GNOME22@*loadURL: gnome-url-show '%s' +@GNOME22@*manualCommand: gnome-terminal --title '%s manual' \ +@GNOME22@ --command '/bin/sh -c "man %s; read foo"' +! +! Gnome 1.4: +! +! *loadURL: gnome-moz-remote --newwin '%s' +! *manualCommand: gnome-help-browser 'man:%s' +! +! non-Gnome systems: +! +@NOGNOME@*loadURL: firefox '%s' || mozilla '%s' || netscape '%s' +@NOGNOME@*manualCommand: xterm -sb -fg black -bg gray75 -T '%s manual' \ +@NOGNOME@ -e /bin/sh -c 'man "%s" ; read foo' + + +! The format used for printing the date and time in the password dialog box +! (see the strftime(3) manual page for details.) +*dateFormat: %d-%b-%y (%a); %I:%M %p +! To show the time only: +! *dateFormat: %I:%M %p +! For 24 hour time: +! *dateFormat: %H:%M + + +! This command is executed by the "New Login" button on the lock dialog. +! (That button does not appear on the dialog if this program does not exist.) +! For Gnome: probably "gdmflexiserver -ls". KDE, probably "kdmctl reserve". +! Or maybe yet another wheel-reinvention, "lxdm -c USER_SWITCH". +! +@NEW_LOGIN_COMMAND_P@*newLoginCommand: @NEW_LOGIN_COMMAND@ + + +! Turning on "installColormap" on 8-bit systems interacts erratically with +! certain jurassic window managers. If your screen turns some color other +! than black, the window manager is buggy, and you need to set this resource +! to false. Or switch WMs. Or join the 21st century and get a 24-bit +! graphics card. +! +*installColormap: True + + +! This is the list of installed screen saver modes. See "man xscreensaver" +! for the syntax used here. +! +! If you want to disable a screensaver, DO NOT remove it from this list: +! instead, mark it as inactive by placing a "-" at the beginning of the line. +! +! You can use the `xscreensaver-demo' program to edit the current list of +! screen savers interactively. +! +*programs: \ + maze -root \n\ +@GL_KLUDGE@ GL: superquadrics -root \n\ + attraction -root \n\ + blitspin -root \n\ + greynetic -root \n\ + helix -root \n\ + hopalong -root \n\ + imsmap -root \n\ +- noseguy -root \n\ +- pyro -root \n\ + qix -root \n\ +- rocks -root \n\ + rorschach -root \n\ + decayscreen -root \n\ + flame -root \n\ + halo -root \n\ + slidescreen -root \n\ + pedal -root \n\ + bouboule -root \n\ +- braid -root \n\ + coral -root \n\ + deco -root \n\ + drift -root \n\ +- fadeplot -root \n\ + galaxy -root \n\ + goop -root \n\ + grav -root \n\ + ifs -root \n\ +@GL_KLUDGE@ GL: jigsaw -root \n\ + julia -root \n\ +- kaleidescope -root \n\ +@GL_KLUDGE@ GL: moebius -root \n\ + moire -root \n\ +@GL_KLUDGE@ GL: morph3d -root \n\ + mountain -root \n\ + munch -root \n\ + penrose -root \n\ +@GL_KLUDGE@ GL: pipes -root \n\ + rd-bomb -root \n\ +@GL_KLUDGE@ GL: rubik -root \n\ +- sierpinski -root \n\ + slip -root \n\ +@GL_KLUDGE@ GL: sproingies -root \n\ + starfish -root \n\ + strange -root \n\ + swirl -root \n\ + triangle -root \n\ + xjack -root \n\ + xlyap -root \n\ +@GL_KLUDGE@ GL: atlantis -root \n\ + bsod -root \n\ +@GL_KLUDGE@ GL: bubble3d -root \n\ +@GL_KLUDGE@ GL: cage -root \n\ +- crystal -root \n\ + cynosure -root \n\ + discrete -root \n\ + distort -root \n\ + epicycle -root \n\ + flow -root \n\ +- GL: glplanet -root \n\ + interference -root \n\ + kumppa -root \n\ +@GL_KLUDGE@ GL: lament -root \n\ + moire2 -root \n\ +@GL_KLUDGE@ GL: sonar -root \n\ +@GL_KLUDGE@ GL: stairs -root \n\ + truchet -root \n\ +- vidwhacker -root \n\ + blaster -root \n\ + bumps -root \n\ + ccurve -root \n\ + compass -root \n\ + deluxe -root \n\ +- demon -root \n\ +@GLE_KLUDGE@ GL: extrusion -root \n\ +- loop -root \n\ + penetrate -root \n\ + petri -root \n\ + phosphor -root \n\ +@GL_KLUDGE@ GL: pulsar -root \n\ + ripples -root \n\ + shadebobs -root \n\ +@GL_KLUDGE@ GL: sierpinski3d -root \n\ + spotlight -root \n\ + squiral -root \n\ + wander -root \n\ +- webcollage -root \n\ + xflame -root \n\ + xmatrix -root \n\ +@GL_KLUDGE@ GL: gflux -root \n\ +- nerverot -root \n\ + xrayswarm -root \n\ + xspirograph -root \n\ +@GL_KLUDGE@ GL: circuit -root \n\ +@GL_KLUDGE@ GL: dangerball -root \n\ +- GL: dnalogo -root \n\ +@GL_KLUDGE@ GL: engine -root \n\ +@GL_KLUDGE@ GL: flipscreen3d -root \n\ +@GL_KLUDGE@ GL: gltext -root \n\ +@GL_KLUDGE@ GL: menger -root \n\ +@GL_KLUDGE@ GL: molecule -root \n\ + rotzoomer -root \n\ + speedmine -root \n\ +@GL_KLUDGE@ GL: starwars -root \n\ +@GL_KLUDGE@ GL: stonerview -root \n\ + vermiculate -root \n\ + whirlwindwarp -root \n\ + zoom -root \n\ + anemone -root \n\ + apollonian -root \n\ +@GL_KLUDGE@ GL: boxed -root \n\ +@GL_KLUDGE@ GL: cubenetic -root \n\ +@GL_KLUDGE@ GL: endgame -root \n\ + euler2d -root \n\ + fluidballs -root \n\ +@GL_KLUDGE@ GL: flurry -root \n\ +- GL: glblur -root \n\ +@GL_KLUDGE@ GL: glsnake -root \n\ + halftone -root \n\ +@GL_KLUDGE@ GL: juggler3d -root \n\ +@GL_KLUDGE@ GL: lavalite -root \n\ +- polyominoes -root \n\ +@GL_KLUDGE@ GL: queens -root \n\ +- GL: sballs -root \n\ +@GL_KLUDGE@ GL: spheremonics -root \n\ +- thornbird -root \n\ + twang -root \n\ +- GL: antspotlight -root \n\ + apple2 -root \n\ +@GL_KLUDGE@ GL: atunnel -root \n\ + barcode -root \n\ +@GL_KLUDGE@ GL: blinkbox -root \n\ +@GL_KLUDGE@ GL: blocktube -root \n\ +@GL_KLUDGE@ GL: bouncingcow -root \n\ + cloudlife -root \n\ +@GL_KLUDGE@ GL: cubestorm -root \n\ + eruption -root \n\ +@GL_KLUDGE@ GL: flipflop -root \n\ +@GL_KLUDGE@ GL: flyingtoasters -root \n\ + fontglide -root \n\ +@GL_KLUDGE@ GL: gleidescope -root \n\ +@GL_KLUDGE@ GL: glknots -root \n\ +@GL_KLUDGE@ GL: glmatrix -root \n\ +- GL: glslideshow -root \n\ +@GL_KLUDGE@ GL: hypertorus -root \n\ +- GL: jigglypuff -root \n\ + metaballs -root \n\ +@GL_KLUDGE@ GL: mirrorblob -root \n\ + piecewise -root \n\ +@GL_KLUDGE@ GL: polytopes -root \n\ + pong -root \n\ + popsquares -root \n\ +@GL_KLUDGE@ GL: surfaces -root \n\ + xanalogtv -root \n\ +- abstractile -root \n\ + anemotaxis -root \n\ +- GL: antinspect -root \n\ + fireworkx -root \n\ + fuzzyflakes -root \n\ + interaggregate -root \n\ + intermomentary -root \n\ + memscroller -root \n\ +@GL_KLUDGE@ GL: noof -root \n\ + pacman -root \n\ +@GL_KLUDGE@ GL: pinion -root \n\ +@GL_KLUDGE@ GL: polyhedra -root \n\ +- GL: providence -root \n\ + substrate -root \n\ + wormhole -root \n\ +- GL: antmaze -root \n\ +@GL_KLUDGE@ GL: boing -root \n\ + boxfit -root \n\ +@GL_KLUDGE@ GL: carousel -root \n\ + celtic -root \n\ +@GL_KLUDGE@ GL: crackberg -root \n\ +@GL_KLUDGE@ GL: cube21 -root \n\ + fiberlamp -root \n\ +@GL_KLUDGE@ GL: fliptext -root \n\ +@GL_KLUDGE@ GL: glhanoi -root \n\ +@GL_KLUDGE@ GL: tangram -root \n\ +@GL_KLUDGE@ GL: timetunnel -root \n\ +@GL_KLUDGE@ GL: glschool -root \n\ +@GL_KLUDGE@ GL: topblock -root \n\ +@GL_KLUDGE@ GL: cubicgrid -root \n\ + cwaves -root \n\ +@GL_KLUDGE@ GL: gears -root \n\ +@GL_KLUDGE@ GL: glcells -root \n\ +@GL_KLUDGE@ GL: lockward -root \n\ + m6502 -root \n\ +@GL_KLUDGE@ GL: moebiusgears -root \n\ +@GL_KLUDGE@ GL: voronoi -root \n\ +@GL_KLUDGE@ GL: hypnowheel -root \n\ +@GL_KLUDGE@ GL: klein -root \n\ +- lcdscrub -root \n\ +@GL_KLUDGE@ GL: photopile -root \n\ +@GL_KLUDGE@ GL: skytentacles -root \n\ +@GL_KLUDGE@ GL: rubikblocks -root \n\ +@GL_KLUDGE@ GL: companioncube -root \n\ +@GL_KLUDGE@ GL: hilbert -root \n\ +@GL_KLUDGE@ GL: tronbit -root \n\ +@GL_KLUDGE@ GL: geodesic -root \n\ + hexadrop -root \n\ +@GL_KLUDGE@ GL: kaleidocycle -root \n\ +@GL_KLUDGE@ GL: quasicrystal -root \n\ +@GL_KLUDGE@ GL: unknownpleasures -root \n + + + +!============================================================================= +! +! You probably don't want to change anything after this point. +! +!============================================================================= + + +XScreenSaver.pointerPollTime: 0:00:05 +XScreenSaver.pointerHysteresis: 10 +XScreenSaver.initialDelay: 0:00:00 +XScreenSaver.windowCreationTimeout: 0:00:30 +XScreenSaver.bourneShell: /bin/sh + + +! Resources for the password and splash-screen dialog boxes of +! the "xscreensaver" daemon. +! +*Dialog.headingFont: *-helvetica-bold-r-*-*-*-180-*-*-*-iso8859-1 +*Dialog.bodyFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*Dialog.labelFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*Dialog.unameFont: *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1 +*Dialog.buttonFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1 +*Dialog.dateFont: *-helvetica-medium-r-*-*-*-80-*-*-*-iso8859-1 +! Helvetica asterisks look terrible. +!*passwd.passwdFont: *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1 +*passwd.passwdFont: *-courier-medium-r-*-*-*-140-*-*-*-iso8859-1 + +*Dialog.foreground: #000000 +*Dialog.background: #E6E6E6 +*Dialog.Button.foreground: #000000 +*Dialog.Button.background: #F5F5F5 +!*Dialog.Button.pointBackground: #EAEAEA +!*Dialog.Button.clickBackground: #C3C3C3 +*Dialog.text.foreground: #000000 +*Dialog.text.background: #FFFFFF +*passwd.thermometer.foreground: #4464AC +*passwd.thermometer.background: #FFFFFF +*Dialog.topShadowColor: #FFFFFF +*Dialog.bottomShadowColor: #CECECE +*Dialog.logo.width: 210 +*Dialog.logo.height: 210 +*Dialog.internalBorderWidth: 24 +*Dialog.borderWidth: 1 +*Dialog.shadowThickness: 2 + +*passwd.heading.label: XScreenSaver %s +*passwd.body.label: This screen is locked. +*passwd.unlock.label: OK +*passwd.login.label: New Login +*passwd.user.label: Username: +*passwd.thermometer.width: 8 +*passwd.asterisks: True +*passwd.uname: True + +*splash.heading.label: XScreenSaver %s +*splash.body.label: Copyright © 1991-2013 by +*splash.body2.label: Jamie Zawinski +*splash.demo.label: Settings +*splash.help.label: Help + + +!============================================================================= +! +! Pretty names for the hacks that have unusual capitalization. +! +!============================================================================= + +*hacks.antinspect.name: AntInspect +*hacks.antmaze.name: AntMaze +*hacks.antspotlight.name: AntSpotlight +*hacks.blinkbox.name: BlinkBox +*hacks.blitspin.name: BlitSpin +*hacks.blocktube.name: BlockTube +*hacks.bouncingcow.name: BouncingCow +*hacks.boxfit.name: BoxFit +*hacks.bsod.name: BSOD +*hacks.bubble3d.name: Bubble3D +*hacks.ccurve.name: CCurve +*hacks.cloudlife.name: CloudLife +*hacks.companioncube.name: CompanionCube +*hacks.cubestorm.name: CubeStorm +*hacks.cubicgrid.name: CubicGrid +*hacks.cwaves.name: CWaves +*hacks.dangerball.name: DangerBall +*hacks.decayscreen.name: DecayScreen +*hacks.dnalogo.name: DNA Logo +*hacks.euler2d.name: Euler2D +*hacks.fadeplot.name: FadePlot +*hacks.flipflop.name: FlipFlop +*hacks.flipscreen3d.name: FlipScreen3D +*hacks.fliptext.name: FlipText +*hacks.fluidballs.name: FluidBalls +*hacks.flyingtoasters.name: FlyingToasters +*hacks.fontglide.name: FontGlide +*hacks.fuzzyflakes.name: FuzzyFlakes +*hacks.gflux.name: GFlux +*hacks.gleidescope.name: Gleidescope +*hacks.glforestfire.name: GLForestFire +*hacks.hyperball.name: HyperBall +*hacks.hypercube.name: HyperCube +*hacks.ifs.name: IFS +*hacks.imsmap.name: IMSMap +*hacks.jigglypuff.name: JigglyPuff +*hacks.juggler3d.name: Juggler3D +*hacks.lcdscrub.name: LCDscrub +*hacks.lmorph.name: LMorph +*hacks.m6502.name: m6502 +*hacks.memscroller.name: MemScroller +*hacks.metaballs.name: MetaBalls +*hacks.mirrorblob.name: MirrorBlob +*hacks.moebiusgears.name: MoebiusGears +*hacks.morph3d.name: Morph3D +*hacks.nerverot.name: NerveRot +*hacks.noseguy.name: NoseGuy +*hacks.popsquares.name: PopSquares +*hacks.quasicrystal.name: QuasiCrystal +*hacks.rd-bomb.name: RDbomb +*hacks.rdbomb.name: RDbomb +*hacks.rotzoomer.name: RotZoomer +*hacks.rubikblocks.name: RubikBlocks +*hacks.sballs.name: SBalls +*hacks.shadebobs.name: ShadeBobs +*hacks.sierpinski3d.name: Sierpinski3D +*hacks.skytentacles.name: SkyTentacles +*hacks.slidescreen.name: SlideScreen +*hacks.speedmine.name: SpeedMine +*hacks.starwars.name: StarWars +*hacks.stonerview.name: StonerView +*hacks.t3d.name: T3D +*hacks.timetunnel.name: TimeTunnel +*hacks.topblock.name: TopBlock +*hacks.tronbit.name: TronBit +*hacks.unknownpleasures.name:UnknownPleasures +*hacks.vidwhacker.name: VidWhacker +*hacks.webcollage.name: WebCollage +*hacks.whirlwindwarp.name: WhirlWindWarp +*hacks.xanalogtv.name: XAnalogTV +*hacks.xrayswarm.name: XRaySwarm + +! obsolete, but still used by xscreensaver-demo-Xm. +*hacks.documentation.isInstalled: True + +! (xrdb prevention kludge: whole file) */ diff --git a/driver/XScreenSaver_Xm_ad.h b/driver/XScreenSaver_Xm_ad.h new file mode 100644 index 00000000..371e0a29 --- /dev/null +++ b/driver/XScreenSaver_Xm_ad.h @@ -0,0 +1,108 @@ +"*fontList: *-helvetica-medium-r-*-*-*-120-*-*-*-iso8859-1", +"*demoDialog*label1.fontList: *-helvetica-medium-r-*-*-*-140-*-*-*-iso8859-1", +"*cmdText.fontList: *-courier-medium-r-*-*-*-120-*-*-*-iso8859-1", +"*label0.fontList: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"XScreenSaver*doc.fontList: *-helvetica-medium-r-*-*-*-100-*-*-*-iso8859-1", +"*foreground: #000000", +"*background: #C0C0C0", +"*XmTextField.foreground: #000000", +"*XmTextField.background: #FFFFFF", +"*list.foreground: #000000", +"*list.background: #FFFFFF", +"*ApplicationShell.title: XScreenSaver", +"*warning.title: XScreenSaver", +"*warning_popup.title: XScreenSaver", +"*allowShellResize: True", +"*autoUnmanage: False", +"*menubar*file.labelString: File", +"*menubar*file.mnemonic: F", +"*file.blank.labelString: Blank Screen Now", +"*file.blank.mnemonic: B", +"*file.lock.labelString: Lock Screen Now", +"*file.lock.mnemonic: L", +"*file.kill.labelString: Kill Daemon", +"*file.kill.mnemonic: K", +"*file.restart.labelString: Restart Daemon", +"*file.restart.mnemonic: R", +"*file.exit.labelString: Exit", +"*file.exit.mnemonic: E", +"*menubar*edit.labelString: Edit", +"*menubar*edit.mnemonic: E", +"*edit.cut.labelString: Cut", +"*edit.cut.mnemonic: u", +"*edit.copy.labelString: Copy", +"*edit.copy.mnemonic: C", +"*edit.paste.labelString: Paste", +"*edit.paste.mnemonic: P", +"*menubar*help.labelString: Help", +"*menubar*help.mnemonic: H", +"*help.about.labelString: About...", +"*help.about.mnemonic: A", +"*help.docMenu.labelString: Documentation...", +"*help.docMenu.mnemonic: D", +"*demoTab.marginWidth: 10", +"*optionsTab.marginWidth: 10", +"*XmScrolledWindow.topOffset: 10", +"*XmScrolledWindow.leftOffset: 10", +"*demoTab.topOffset: 4", +"*form1.bottomOffset: 10", +"*form3.leftOffset: 10", +"*form3.rightOffset: 10", +"*frame.topOffset: 10", +"*frame.bottomOffset: 10", +"*enabled.topOffset: 10", +"*visLabel.topOffset: 10", +"*combo.topOffset: 10", +"*form4.bottomOffset: 4", +"*hr.bottomOffset: 4", +"*XmComboBox.marginWidth: 0", +"*XmComboBox.marginHeight: 0", +"*demo.marginWidth: 30", +"*demo.marginHeight: 4", +"*man.marginWidth: 10", +"*man.marginHeight: 4", +"*down.leftOffset: 40", +"*down.marginWidth: 4", +"*down.marginHeight: 4", +"*up.marginWidth: 4", +"*up.marginHeight: 4", +"*frame.traversalOn: False", +"*list.automaticSelection: True", +"*list.visibleItemCount: 20", +"*doc.columns: 60", +"*combo.columns: 11", +"*demoTab.labelString: Graphics Demos", +"*optionsTab.labelString: Screensaver Options", +"*down.labelString: \\\\/ ", +"*up.labelString: /\\\\ ", +"*frameLabel.labelString: ", +"*cmdLabel.labelString: Command Line:", +"*cmdLabel.alignment: ALIGNMENT_BEGINNING", +"*enabled.labelString: Enabled", +"*visLabel.labelString: Visual:", +"*visLabel.alignment: ALIGNMENT_END", +"*visLabel.leftOffset: 20", +"*demo.labelString: Demo", +"*man.labelString: Documentation...", +"*done.labelString: Quit", +"*preferencesLabel.labelString: XScreenSaver Parameters", +"*timeoutLabel.labelString: Saver Timeout", +"*cycleLabel.labelString: Cycle Timeout", +"*fadeSecondsLabel.labelString: Fade Duration", +"*fadeTicksLabel.labelString: Fade Ticks", +"*lockLabel.labelString: Lock Timeout", +"*passwdLabel.labelString: Password Timeout", +"*preferencesForm*XmTextField.columns: 8", +"*verboseToggle.labelString: Verbose", +"*cmapToggle.labelString: Install Colormap", +"*fadeToggle.labelString: Fade Colormap", +"*unfadeToggle.labelString: Unfade Colormap", +"*lockToggle.labelString: Require Password", +"*OK.marginWidth: 30", +"*OK.marginHeight: 4", +"*OK.leftOffset: 10", +"*OK.bottomOffset: 10", +"*Cancel.marginWidth: 30", +"*Cancel.marginHeight: 4", +"*Cancel.rightOffset: 10", +"*Cancel.bottomOffset: 10", diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h new file mode 100644 index 00000000..ae68ab9a --- /dev/null +++ b/driver/XScreenSaver_ad.h @@ -0,0 +1,371 @@ +"#error Do not run app-defaults files through xrdb!", +"#error That does not do what you might expect.", +"#error Put this file in /usr/lib/X11/app-defaults/XScreenSaver instead.", +"*mode: random", +"*timeout: 0:10:00", +"*cycle: 0:10:00", +"*lockTimeout: 0:00:00", +"*passwdTimeout: 0:00:30", +"*dpmsEnabled: False", +"*dpmsQuickoffEnabled: False", +"*dpmsStandby: 2:00:00", +"*dpmsSuspend: 2:00:00", +"*dpmsOff: 4:00:00", +"*grabDesktopImages: True", +"*grabVideoFrames: False", +"*chooseRandomImages: True", +"*imageDirectory: /Library/Desktop Pictures/", +"*nice: 10", +"*memoryLimit: 0", +"*lock: False", +"*verbose: False", +"*timestamp: True", +"*fade: True", +"*unfade: False", +"*fadeSeconds: 0:00:03", +"*fadeTicks: 20", +"*splash: True", +"*splashDuration: 0:00:05", +"*visualID: default", +"*captureStderr: True", +"*ignoreUninstalledPrograms: False", +"*textMode: file", +"*textLiteral: XScreenSaver", +"*textFile: ", +"*textProgram: fortune", +"*textURL: http://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss", +"*overlayTextForeground: #FFFF00", +"*overlayTextBackground: #000000", +"*overlayStderr: True", +"*font: *-medium-r-*-140-*-m-*", +"*sgiSaverExtension: True", +"*xidleExtension: True", +"*procInterrupts: True", +"*xinputExtensionDev: False", +"GetViewPortIsFullOfLies: False", +"*demoCommand: xscreensaver-demo", +"*prefsCommand: xscreensaver-demo -prefs", +"*helpURL: http://www.jwz.org/xscreensaver/man.html", +"*loadURL: gnome-open '%s'", +"*manualCommand: gnome-terminal --title '%s manual' \ + --command '/bin/sh -c \"man %s; read foo\"'", +"*dateFormat: %d-%b-%y (%a); %I:%M %p", +"*installColormap: True", +"*programs: \ + maze -root \\n\ + GL: superquadrics -root \\n\ + attraction -root \\n\ + blitspin -root \\n\ + greynetic -root \\n\ + helix -root \\n\ + hopalong -root \\n\ + imsmap -root \\n\ +- noseguy -root \\n\ +- pyro -root \\n\ + qix -root \\n\ +- rocks -root \\n\ + rorschach -root \\n\ + decayscreen -root \\n\ + flame -root \\n\ + halo -root \\n\ + slidescreen -root \\n\ + pedal -root \\n\ + bouboule -root \\n\ +- braid -root \\n\ + coral -root \\n\ + deco -root \\n\ + drift -root \\n\ +- fadeplot -root \\n\ + galaxy -root \\n\ + goop -root \\n\ + grav -root \\n\ + ifs -root \\n\ + GL: jigsaw -root \\n\ + julia -root \\n\ +- kaleidescope -root \\n\ + GL: moebius -root \\n\ + moire -root \\n\ + GL: morph3d -root \\n\ + mountain -root \\n\ + munch -root \\n\ + penrose -root \\n\ + GL: pipes -root \\n\ + rd-bomb -root \\n\ + GL: rubik -root \\n\ +- sierpinski -root \\n\ + slip -root \\n\ + GL: sproingies -root \\n\ + starfish -root \\n\ + strange -root \\n\ + swirl -root \\n\ + triangle -root \\n\ + xjack -root \\n\ + xlyap -root \\n\ + GL: atlantis -root \\n\ + bsod -root \\n\ + GL: bubble3d -root \\n\ + GL: cage -root \\n\ +- crystal -root \\n\ + cynosure -root \\n\ + discrete -root \\n\ + distort -root \\n\ + epicycle -root \\n\ + flow -root \\n\ +- GL: glplanet -root \\n\ + interference -root \\n\ + kumppa -root \\n\ + GL: lament -root \\n\ + moire2 -root \\n\ + GL: sonar -root \\n\ + GL: stairs -root \\n\ + truchet -root \\n\ +- vidwhacker -root \\n\ + blaster -root \\n\ + bumps -root \\n\ + ccurve -root \\n\ + compass -root \\n\ + deluxe -root \\n\ +- demon -root \\n\ +- GL: extrusion -root \\n\ +- loop -root \\n\ + penetrate -root \\n\ + petri -root \\n\ + phosphor -root \\n\ + GL: pulsar -root \\n\ + ripples -root \\n\ + shadebobs -root \\n\ + GL: sierpinski3d -root \\n\ + spotlight -root \\n\ + squiral -root \\n\ + wander -root \\n\ +- webcollage -root \\n\ + xflame -root \\n\ + xmatrix -root \\n\ + GL: gflux -root \\n\ +- nerverot -root \\n\ + xrayswarm -root \\n\ + xspirograph -root \\n\ + GL: circuit -root \\n\ + GL: dangerball -root \\n\ +- GL: dnalogo -root \\n\ + GL: engine -root \\n\ + GL: flipscreen3d -root \\n\ + GL: gltext -root \\n\ + GL: menger -root \\n\ + GL: molecule -root \\n\ + rotzoomer -root \\n\ + speedmine -root \\n\ + GL: starwars -root \\n\ + GL: stonerview -root \\n\ + vermiculate -root \\n\ + whirlwindwarp -root \\n\ + zoom -root \\n\ + anemone -root \\n\ + apollonian -root \\n\ + GL: boxed -root \\n\ + GL: cubenetic -root \\n\ + GL: endgame -root \\n\ + euler2d -root \\n\ + fluidballs -root \\n\ + GL: flurry -root \\n\ +- GL: glblur -root \\n\ + GL: glsnake -root \\n\ + halftone -root \\n\ + GL: juggler3d -root \\n\ + GL: lavalite -root \\n\ +- polyominoes -root \\n\ + GL: queens -root \\n\ +- GL: sballs -root \\n\ + GL: spheremonics -root \\n\ +- thornbird -root \\n\ + twang -root \\n\ +- GL: antspotlight -root \\n\ + apple2 -root \\n\ + GL: atunnel -root \\n\ + barcode -root \\n\ + GL: blinkbox -root \\n\ + GL: blocktube -root \\n\ + GL: bouncingcow -root \\n\ + cloudlife -root \\n\ + GL: cubestorm -root \\n\ + eruption -root \\n\ + GL: flipflop -root \\n\ + GL: flyingtoasters -root \\n\ + fontglide -root \\n\ + GL: gleidescope -root \\n\ + GL: glknots -root \\n\ + GL: glmatrix -root \\n\ +- GL: glslideshow -root \\n\ + GL: hypertorus -root \\n\ +- GL: jigglypuff -root \\n\ + metaballs -root \\n\ + GL: mirrorblob -root \\n\ + piecewise -root \\n\ + GL: polytopes -root \\n\ + pong -root \\n\ + popsquares -root \\n\ + GL: surfaces -root \\n\ + xanalogtv -root \\n\ +- abstractile -root \\n\ + anemotaxis -root \\n\ +- GL: antinspect -root \\n\ + fireworkx -root \\n\ + fuzzyflakes -root \\n\ + interaggregate -root \\n\ + intermomentary -root \\n\ + memscroller -root \\n\ + GL: noof -root \\n\ + pacman -root \\n\ + GL: pinion -root \\n\ + GL: polyhedra -root \\n\ +- GL: providence -root \\n\ + substrate -root \\n\ + wormhole -root \\n\ +- GL: antmaze -root \\n\ + GL: boing -root \\n\ + boxfit -root \\n\ + GL: carousel -root \\n\ + celtic -root \\n\ + GL: crackberg -root \\n\ + GL: cube21 -root \\n\ + fiberlamp -root \\n\ + GL: fliptext -root \\n\ + GL: glhanoi -root \\n\ + GL: tangram -root \\n\ + GL: timetunnel -root \\n\ + GL: glschool -root \\n\ + GL: topblock -root \\n\ + GL: cubicgrid -root \\n\ + cwaves -root \\n\ + GL: gears -root \\n\ + GL: glcells -root \\n\ + GL: lockward -root \\n\ + m6502 -root \\n\ + GL: moebiusgears -root \\n\ + GL: voronoi -root \\n\ + GL: hypnowheel -root \\n\ + GL: klein -root \\n\ +- lcdscrub -root \\n\ + GL: photopile -root \\n\ + GL: skytentacles -root \\n\ + GL: rubikblocks -root \\n\ + GL: companioncube -root \\n\ + GL: hilbert -root \\n\ + GL: tronbit -root \\n\ + GL: geodesic -root \\n\ + hexadrop -root \\n\ + GL: kaleidocycle -root \\n\ + GL: quasicrystal -root \\n\ + GL: unknownpleasures -root \\n", +"XScreenSaver.pointerPollTime: 0:00:05", +"XScreenSaver.pointerHysteresis: 10", +"XScreenSaver.initialDelay: 0:00:00", +"XScreenSaver.windowCreationTimeout: 0:00:30", +"XScreenSaver.bourneShell: /bin/sh", +"*Dialog.headingFont: *-helvetica-bold-r-*-*-*-180-*-*-*-iso8859-1", +"*Dialog.bodyFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.labelFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.unameFont: *-helvetica-bold-r-*-*-*-120-*-*-*-iso8859-1", +"*Dialog.buttonFont: *-helvetica-bold-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.dateFont: *-helvetica-medium-r-*-*-*-80-*-*-*-iso8859-1", +"*passwd.passwdFont: *-courier-medium-r-*-*-*-140-*-*-*-iso8859-1", +"*Dialog.foreground: #000000", +"*Dialog.background: #E6E6E6", +"*Dialog.Button.foreground: #000000", +"*Dialog.Button.background: #F5F5F5", +"*Dialog.text.foreground: #000000", +"*Dialog.text.background: #FFFFFF", +"*passwd.thermometer.foreground: #4464AC", +"*passwd.thermometer.background: #FFFFFF", +"*Dialog.topShadowColor: #FFFFFF", +"*Dialog.bottomShadowColor: #CECECE", +"*Dialog.logo.width: 210", +"*Dialog.logo.height: 210", +"*Dialog.internalBorderWidth: 24", +"*Dialog.borderWidth: 1", +"*Dialog.shadowThickness: 2", +"*passwd.heading.label: XScreenSaver %s", +"*passwd.body.label: This screen is locked.", +"*passwd.unlock.label: OK", +"*passwd.login.label: New Login", +"*passwd.user.label: Username:", +"*passwd.thermometer.width: 8", +"*passwd.asterisks: True", +"*passwd.uname: True", +"*splash.heading.label: XScreenSaver %s", +"*splash.body.label: Copyright © 1991-2013 by", +"*splash.body2.label: Jamie Zawinski ", +"*splash.demo.label: Settings", +"*splash.help.label: Help", +"*hacks.antinspect.name: AntInspect", +"*hacks.antmaze.name: AntMaze", +"*hacks.antspotlight.name: AntSpotlight", +"*hacks.blinkbox.name: BlinkBox", +"*hacks.blitspin.name: BlitSpin", +"*hacks.blocktube.name: BlockTube", +"*hacks.bouncingcow.name: BouncingCow", +"*hacks.boxfit.name: BoxFit", +"*hacks.bsod.name: BSOD", +"*hacks.bubble3d.name: Bubble3D", +"*hacks.ccurve.name: CCurve", +"*hacks.cloudlife.name: CloudLife", +"*hacks.companioncube.name: CompanionCube", +"*hacks.cubestorm.name: CubeStorm", +"*hacks.cubicgrid.name: CubicGrid", +"*hacks.cwaves.name: CWaves", +"*hacks.dangerball.name: DangerBall", +"*hacks.decayscreen.name: DecayScreen", +"*hacks.dnalogo.name: DNA Logo", +"*hacks.euler2d.name: Euler2D", +"*hacks.fadeplot.name: FadePlot", +"*hacks.flipflop.name: FlipFlop", +"*hacks.flipscreen3d.name: FlipScreen3D", +"*hacks.fliptext.name: FlipText", +"*hacks.fluidballs.name: FluidBalls", +"*hacks.flyingtoasters.name: FlyingToasters", +"*hacks.fontglide.name: FontGlide", +"*hacks.fuzzyflakes.name: FuzzyFlakes", +"*hacks.gflux.name: GFlux", +"*hacks.gleidescope.name: Gleidescope", +"*hacks.glforestfire.name: GLForestFire", +"*hacks.hyperball.name: HyperBall", +"*hacks.hypercube.name: HyperCube", +"*hacks.ifs.name: IFS", +"*hacks.imsmap.name: IMSMap", +"*hacks.jigglypuff.name: JigglyPuff", +"*hacks.juggler3d.name: Juggler3D", +"*hacks.lcdscrub.name: LCDscrub", +"*hacks.lmorph.name: LMorph", +"*hacks.m6502.name: m6502", +"*hacks.memscroller.name: MemScroller", +"*hacks.metaballs.name: MetaBalls", +"*hacks.mirrorblob.name: MirrorBlob", +"*hacks.moebiusgears.name: MoebiusGears", +"*hacks.morph3d.name: Morph3D", +"*hacks.nerverot.name: NerveRot", +"*hacks.noseguy.name: NoseGuy", +"*hacks.popsquares.name: PopSquares", +"*hacks.quasicrystal.name: QuasiCrystal", +"*hacks.rd-bomb.name: RDbomb", +"*hacks.rdbomb.name: RDbomb", +"*hacks.rotzoomer.name: RotZoomer", +"*hacks.rubikblocks.name: RubikBlocks", +"*hacks.sballs.name: SBalls", +"*hacks.shadebobs.name: ShadeBobs", +"*hacks.sierpinski3d.name: Sierpinski3D", +"*hacks.skytentacles.name: SkyTentacles", +"*hacks.slidescreen.name: SlideScreen", +"*hacks.speedmine.name: SpeedMine", +"*hacks.starwars.name: StarWars", +"*hacks.stonerview.name: StonerView", +"*hacks.t3d.name: T3D", +"*hacks.timetunnel.name: TimeTunnel", +"*hacks.topblock.name: TopBlock", +"*hacks.tronbit.name: TronBit", +"*hacks.unknownpleasures.name:UnknownPleasures", +"*hacks.vidwhacker.name: VidWhacker", +"*hacks.webcollage.name: WebCollage", +"*hacks.whirlwindwarp.name: WhirlWindWarp", +"*hacks.xanalogtv.name: XAnalogTV", +"*hacks.xrayswarm.name: XRaySwarm", +"*hacks.documentation.isInstalled: True", diff --git a/driver/auth.h b/driver/auth.h new file mode 100644 index 00000000..65e00f33 --- /dev/null +++ b/driver/auth.h @@ -0,0 +1,54 @@ +/* auth.h --- Providing authentication mechanisms. + * + * (c) 2007, Quest Software, Inc. All rights reserved. + * + * This file is part of XScreenSaver, + * Copyright (c) 1993-2004 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 XSS_AUTH_H +#define XSS_AUTH_H + +#include "types.h" + +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +struct auth_message { + enum { + AUTH_MSGTYPE_INFO, + AUTH_MSGTYPE_ERROR, + AUTH_MSGTYPE_PROMPT_NOECHO, + AUTH_MSGTYPE_PROMPT_ECHO + } type; + const char *msg; +}; + +struct auth_response { + char *response; +}; + +int +gui_auth_conv(int num_msg, + const struct auth_message auth_msgs[], + struct auth_response **resp, + saver_info *si); + +void +xss_authenticate(saver_info *si, Bool verbose_p); + +void +auth_finished_cb (saver_info *si); + +#endif diff --git a/driver/compile_axp.com b/driver/compile_axp.com new file mode 100644 index 00000000..d6ed0e8a --- /dev/null +++ b/driver/compile_axp.com @@ -0,0 +1,15 @@ +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DEMO.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DIALOGS-XM.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) LOCK.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) PASSWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) STDERR.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) SUBPROCS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) TIMERS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) WINDOWS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSCREENSAVER-COMMAND.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) XSCREENSAVER.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSET.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-GETPWNAM.C +$!!! CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) GETPWUID.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-HPWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-VALIDATE.C diff --git a/driver/compile_decc.com b/driver/compile_decc.com new file mode 100644 index 00000000..d6ed0e8a --- /dev/null +++ b/driver/compile_decc.com @@ -0,0 +1,15 @@ +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DEMO.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) DIALOGS-XM.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) LOCK.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) PASSWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) STDERR.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) SUBPROCS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) TIMERS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) WINDOWS.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSCREENSAVER-COMMAND.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,NO_SETUID)/INCL=([],[-],[-.UTILS]) XSCREENSAVER.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) XSET.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-GETPWNAM.C +$!!! CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) GETPWUID.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-HPWD.C +$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H)/INCL=([],[-],[-.UTILS]) VMS-VALIDATE.C diff --git a/driver/demo-Gtk-conf.c b/driver/demo-Gtk-conf.c new file mode 100644 index 00000000..2f03a12f --- /dev/null +++ b/driver/demo-Gtk-conf.c @@ -0,0 +1,1997 @@ +/* demo-Gtk-conf.c --- implements the dynamic configuration dialogs. + * xscreensaver, Copyright (c) 2001-2013 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(HAVE_GTK) && defined(HAVE_XML) /* whole file */ + +#include + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +/* + * Both of these workarounds can be removed when support for ancient + * libxml versions is dropped. versions 1.8.11 and 2.3.4 provide the + * correct fixes. + */ + +/* + * Older libxml polluted the global headerspace, while libxml2 fixed + * this. To support both old and recent libxmls, we have this + * workaround. + */ +#ifdef HAVE_OLD_XML_HEADERS +# include +#else /* ! HAVE_OLD_XML_HEADERS */ +# include +#endif /* HAVE_OLD_XML_HEADERS */ + +/* + * handle non-native spelling mistakes in earlier versions and provide + * the source-compat fix for this that may not be in older versions. + */ +#ifndef xmlChildrenNode +# if LIBXML_VERSION >= 20000 +# define xmlChildrenNode children +# define xmlRootNode children +# else +# define xmlChildrenNode childs +# define xmlRootNode root +# endif /* LIBXML_VERSION */ +#endif /* xmlChildrenNode */ + +#include + +#include "demo-Gtk-conf.h" + +/* Deal with deprecation of direct access to struct fields on the way to GTK3 + See http://live.gnome.org/GnomeGoals/UseGseal + */ +#if GTK_CHECK_VERSION(2,14,0) +# define GET_PARENT(w) gtk_widget_get_parent (w) +# define GET_ADJ_VALUE(a) gtk_adjustment_get_value (a) +# define GET_ADJ_UPPER(a) gtk_adjustment_get_upper (a) +# define GET_ADJ_LOWER(a) gtk_adjustment_get_lower (a) +#else +# define GET_PARENT(w) ((w)->parent) +# define GET_ADJ_VALUE(a) ((a)->value) +# define GET_ADJ_UPPER(a) ((a)->upper) +# define GET_ADJ_LOWER(a) ((a)->lower) +#endif + + +extern const char *blurb (void); + + +const char *hack_configuration_path = HACK_CONFIGURATION_PATH; + +static gboolean debug_p = FALSE; + + +#define MIN_SLIDER_WIDTH 150 +#define MIN_SPINBUTTON_WIDTH 48 +#define MIN_LABEL_WIDTH 70 + + +typedef enum { + COMMAND, + FAKE, + DESCRIPTION, + FAKEPREVIEW, + STRING, + FILENAME, + SLIDER, + SPINBUTTON, + BOOLEAN, + SELECT, + SELECT_OPTION +} parameter_type; + + +typedef struct { + + parameter_type type; + + xmlChar *id; /* widget name */ + xmlChar *label; /* heading label, or null */ + + /* command, fake, description, fakepreview, string, file + */ + xmlChar *string; /* file name, description, whatever. */ + + /* slider, spinbutton + */ + xmlChar *low_label; /* label for the left side */ + xmlChar *high_label; /* label for the right side */ + float low; /* minimum value */ + float high; /* maximum value */ + float value; /* default value */ + gboolean integer_p; /* whether the range is integral, or real */ + xmlChar *arg; /* command-line option to set (substitute "%") */ + gboolean invert_p; /* whether to flip the value and pretend the + range goes from hi-low instead of low-hi. */ + + /* boolean, select-option + */ + xmlChar *arg_set; /* command-line option to set for "yes", or null */ + xmlChar *arg_unset; /* command-line option to set for "no", or null */ + + /* select + */ + GList *options; + + /* select_option + */ + GtkWidget *widget; + +} parameter; + + +static parameter *make_select_option (const char *file, xmlNodePtr); +static void make_parameter_widget (const char *filename, + parameter *, GtkWidget *); +static void browse_button_cb (GtkButton *button, gpointer user_data); + + +/* Frees the parameter object and all strings and sub-parameters. + Does not destroy the widget, if any. + */ +static void +free_parameter (parameter *p) +{ + GList *rest; + if (p->id) free (p->id); + if (p->label) free (p->label); + if (p->string) free (p->string); + if (p->low_label) free (p->low_label); + if (p->high_label) free (p->high_label); + if (p->arg) free (p->arg); + if (p->arg_set) free (p->arg_set); + if (p->arg_unset) free (p->arg_unset); + + for (rest = p->options; rest; rest = rest->next) + if (rest->data) + free_parameter ((parameter *) rest->data); + + memset (p, ~0, sizeof(*p)); + free (p); +} + + +/* Debugging: dumps out a `parameter' structure. + */ +#if 0 +void +describe_parameter (FILE *out, parameter *p) +{ + fprintf (out, "<"); + switch (p->type) + { + case COMMAND: fprintf (out, "command"); break; + case FAKE: fprintf (out, "fake"); break; + case DESCRIPTION: fprintf (out, "_description"); break; + case FAKEPREVIEW: fprintf (out, "fakepreview"); break; + case STRING: fprintf (out, "string"); break; + case FILENAME: fprintf (out, "filename"); break; + case SLIDER: fprintf (out, "number type=\"slider\""); break; + case SPINBUTTON: fprintf (out, "number type=\"spinbutton\""); break; + case BOOLEAN: fprintf (out, "boolean"); break; + case SELECT: fprintf (out, "select"); break; + default: abort(); break; + } + if (p->id) fprintf (out, " id=\"%s\"", p->id); + if (p->label) fprintf (out, " _label=\"%s\"", p->label); + if (p->string && p->type != DESCRIPTION) + fprintf (out, " string=\"%s\"", p->string); + if (p->low_label) fprintf (out, " _low-label=\"%s\"", p->low_label); + if (p->high_label) fprintf (out, " _high-label=\"%s\"", p->high_label); + if (p->low) fprintf (out, " low=\"%.2f\"", p->low); + if (p->high) fprintf (out, " high=\"%.2f\"", p->high); + if (p->value) fprintf (out, " default=\"%.2f\"", p->value); + if (p->arg) fprintf (out, " arg=\"%s\"", p->arg); + if (p->invert_p) fprintf (out, " convert=\"invert\""); + if (p->arg_set) fprintf (out, " arg-set=\"%s\"", p->arg_set); + if (p->arg_unset) fprintf (out, " arg-unset=\"%s\"", p->arg_unset); + fprintf (out, ">\n"); + + if (p->type == SELECT) + { + GList *opt; + for (opt = p->options; opt; opt = opt->next) + { + parameter *o = (parameter *) opt->data; + if (o->type != SELECT_OPTION) abort(); + fprintf (out, " id) fprintf (out, " id=\"%s\"", o->id); + if (o->label) fprintf (out, " _label=\"%s\"", o->label); + if (o->arg_set) fprintf (out, " arg-set=\"%s\"", o->arg_set); + if (o->arg_unset) fprintf (out, " arg-unset=\"%s\"", o->arg_unset); + fprintf (out, ">\n"); + } + fprintf (out, "\n"); + } + else if (p->type == DESCRIPTION) + { + if (p->string) + fprintf (out, " %s\n", p->string); + fprintf (out, "\n"); + } +} +#endif /* 0 */ + + +/* Like xmlGetProp() but parses a float out of the string. + If the number was expressed as a float and not an integer + (that is, the string contained a decimal point) then + `floatp' is set to TRUE. Otherwise, it is unchanged. + */ +static float +xml_get_float (xmlNodePtr node, const xmlChar *name, gboolean *floatpP) +{ + const char *s = (char *) xmlGetProp (node, name); + float f; + char c; + if (!s || 1 != sscanf (s, "%f %c", &f, &c)) + return 0; + else + { + if (strchr (s, '.')) *floatpP = TRUE; + return f; + } +} + + +static void sanity_check_parameter (const char *filename, + const xmlChar *node_name, + 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 + to create (comment, or unknown tag.) + */ +static parameter * +make_parameter (const char *filename, xmlNodePtr node) +{ + parameter *p; + const char *name = (char *) node->name; + const char *convert; + gboolean floatp = FALSE; + + if (node->type == XML_COMMENT_NODE) + return 0; + + p = calloc (1, sizeof(*p)); + + if (!name) abort(); + else if (!strcmp (name, "command")) p->type = COMMAND; + else if (!strcmp (name, "fullcommand")) p->type = COMMAND; + else if (!strcmp (name, "_description")) p->type = DESCRIPTION; + else if (!strcmp (name, "fakepreview")) p->type = FAKEPREVIEW; + else if (!strcmp (name, "fake")) p->type = FAKE; + else if (!strcmp (name, "boolean")) p->type = BOOLEAN; + else if (!strcmp (name, "string")) p->type = STRING; + 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") || /* ignored in X11; */ + !strcmp (name, "xscreensaver-image") || /* used in Cocoa. */ + !strcmp (name, "xscreensaver-updater")) + { + free (p); + return 0; + } + else if (node->type == XML_TEXT_NODE) + { + sanity_check_text_node (filename, node); + free (p); + return 0; + } + else + { + if (debug_p) + fprintf (stderr, "%s: WARNING: %s: unknown tag: \"%s\"\n", + blurb(), filename, name); + free (p); + return 0; + } + + if (p->type == SPINBUTTON) + { + const char *type = (char *) xmlGetProp (node, (xmlChar *) "type"); + if (!type || !strcmp (type, "spinbutton")) p->type = SPINBUTTON; + else if (!strcmp (type, "slider")) p->type = SLIDER; + else + { + if (debug_p) + fprintf (stderr, "%s: WARNING: %s: unknown %s type: \"%s\"\n", + blurb(), filename, name, type); + free (p); + return 0; + } + } + else if (p->type == DESCRIPTION) + { + if (node->xmlChildrenNode && + node->xmlChildrenNode->type == XML_TEXT_NODE && + !node->xmlChildrenNode->next) + p->string = (xmlChar *) + strdup ((char *) node->xmlChildrenNode->content); + } + + p->id = xmlGetProp (node, (xmlChar *) "id"); + p->label = xmlGetProp (node, (xmlChar *) "_label"); + p->low_label = xmlGetProp (node, (xmlChar *) "_low-label"); + p->high_label = xmlGetProp (node, (xmlChar *) "_high-label"); + p->low = xml_get_float (node, (xmlChar *) "low", &floatp); + p->high = xml_get_float (node, (xmlChar *) "high", &floatp); + p->value = xml_get_float (node, (xmlChar *) "default", &floatp); + p->integer_p = !floatp; + convert = (char *) xmlGetProp (node, (xmlChar *) "convert"); + p->invert_p = (convert && !strcmp (convert, "invert")); + p->arg = xmlGetProp (node, (xmlChar *) "arg"); + p->arg_set = xmlGetProp (node, (xmlChar *) "arg-set"); + p->arg_unset = xmlGetProp (node, (xmlChar *) "arg-unset"); + + /* Check for missing decimal point */ + if (debug_p && + p->integer_p && + (p->high != p->low) && + (p->high - p->low) <= 1) + fprintf (stderr, + "%s: WARNING: %s: %s: range [%.1f, %.1f] shouldn't be integral!\n", + blurb(), filename, p->id, + p->low, p->high); + + if (p->type == SELECT) + { + xmlNodePtr kids; + for (kids = node->xmlChildrenNode; kids; kids = kids->next) + { + parameter *s = make_select_option (filename, kids); + if (s) + p->options = g_list_append (p->options, s); + } + } + + sanity_check_parameter (filename, (const xmlChar *) name, p); + + return p; +} + + +/* Allocates and returns a new SELECT_OPTION `parameter' object based + on the properties in the given XML node. Returns 0 if there's nothing + to create (comment, or unknown tag.) + */ +static parameter * +make_select_option (const char *filename, xmlNodePtr node) +{ + if (node->type == XML_COMMENT_NODE) + return 0; + else if (node->type == XML_TEXT_NODE) + { + sanity_check_text_node (filename, node); + return 0; + } + else if (node->type != XML_ELEMENT_NODE) + { + if (debug_p) + fprintf (stderr, + "%s: WARNING: %s: %s: unexpected child tag type %d\n", + blurb(), filename, node->name, (int)node->type); + return 0; + } + else if (strcmp ((char *) node->name, "option")) + { + if (debug_p) + fprintf (stderr, + "%s: WARNING: %s: %s: child not an option tag: \"%s\"\n", + blurb(), filename, node->name, node->name); + return 0; + } + else + { + parameter *s = calloc (1, sizeof(*s)); + + 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"); + + sanity_check_parameter (filename, node->name, s); + return s; + } +} + + +/* Rudimentary check to make sure someone hasn't typed "arg-set=" + when they should have typed "arg=", etc. + */ +static void +sanity_check_parameter (const char *filename, const xmlChar *node_name, + parameter *p) +{ + struct { + gboolean id; + gboolean label; + gboolean string; + gboolean low_label; + gboolean high_label; + gboolean low; + gboolean high; + gboolean value; + gboolean arg; + gboolean invert_p; + gboolean arg_set; + gboolean arg_unset; + } allowed, require; + + memset (&allowed, 0, sizeof (allowed)); + memset (&require, 0, sizeof (require)); + + switch (p->type) + { + case COMMAND: + allowed.arg = TRUE; + require.arg = TRUE; + break; + case FAKE: + break; + case DESCRIPTION: + allowed.string = TRUE; + break; + case FAKEPREVIEW: + break; + case STRING: + allowed.id = TRUE; + require.id = TRUE; + allowed.label = TRUE; + require.label = TRUE; + allowed.arg = TRUE; + require.arg = TRUE; + break; + case FILENAME: + allowed.id = TRUE; + require.id = TRUE; + allowed.label = TRUE; + allowed.arg = TRUE; + require.arg = TRUE; + break; + case SLIDER: + allowed.id = TRUE; + require.id = TRUE; + allowed.label = TRUE; + allowed.low_label = TRUE; + allowed.high_label = TRUE; + allowed.arg = TRUE; + require.arg = TRUE; + allowed.low = TRUE; + /* require.low = TRUE; -- may be 0 */ + allowed.high = TRUE; + /* require.high = TRUE; -- may be 0 */ + allowed.value = TRUE; + /* require.value = TRUE; -- may be 0 */ + allowed.invert_p = TRUE; + break; + case SPINBUTTON: + allowed.id = TRUE; + require.id = TRUE; + allowed.label = TRUE; + allowed.arg = TRUE; + require.arg = TRUE; + allowed.low = TRUE; + /* require.low = TRUE; -- may be 0 */ + allowed.high = TRUE; + /* require.high = TRUE; -- may be 0 */ + allowed.value = TRUE; + /* require.value = TRUE; -- may be 0 */ + allowed.invert_p = TRUE; + break; + case BOOLEAN: + allowed.id = TRUE; + require.id = TRUE; + allowed.label = TRUE; + allowed.arg_set = TRUE; + allowed.arg_unset = TRUE; + break; + case SELECT: + allowed.id = TRUE; + require.id = TRUE; + break; + case SELECT_OPTION: + allowed.id = TRUE; + allowed.label = TRUE; + require.label = TRUE; + allowed.arg_set = TRUE; + break; + default: + abort(); + break; + } + +# define WARN(STR) \ + fprintf (stderr, "%s: %s: " STR " in <%s%s id=\"%s\">\n", \ + blurb(), filename, node_name, \ + (!strcmp((char *) node_name, "number") \ + ? (p->type == SPINBUTTON ? " type=spinbutton" : " type=slider")\ + : ""), \ + (p->id ? (char *) p->id : "")) +# define CHECK(SLOT,NAME) \ + if (p->SLOT && !allowed.SLOT) \ + WARN ("\"" NAME "\" is not a valid option"); \ + if (!p->SLOT && require.SLOT) \ + WARN ("\"" NAME "\" is required") + + CHECK (id, "id"); + CHECK (label, "_label"); + CHECK (string, "(body text)"); + CHECK (low_label, "_low-label"); + CHECK (high_label, "_high-label"); + CHECK (low, "low"); + CHECK (high, "high"); + CHECK (value, "default"); + CHECK (arg, "arg"); + CHECK (invert_p, "convert"); + CHECK (arg_set, "arg-set"); + 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. + */ +static void +sanity_check_text_node (const char *filename, const xmlNodePtr node) +{ + const char *body = (const char *) node->content; + if (node->type != XML_TEXT_NODE) abort(); + while (isspace (*body)) body++; + if (*body) + fprintf (stderr, "%s: WARNING: %s: random text present: \"%s\"\n", + blurb(), filename, body); +} + + +/* Returns a list of strings, every switch mentioned in the parameters. + The strings must be freed. + */ +static GList * +get_all_switches (const char *filename, GList *parms) +{ + GList *switches = 0; + GList *p; + for (p = parms; p; p = p->next) + { + parameter *pp = (parameter *) p->data; + + if (pp->type == SELECT) + { + GList *list2 = get_all_switches (filename, pp->options); + switches = g_list_concat (switches, list2); + } + if (pp->arg && *pp->arg) + switches = g_list_append (switches, strdup ((char *) pp->arg)); + if (pp->arg_set && *pp->arg_set) + switches = g_list_append (switches, strdup ((char *) pp->arg_set)); + if (pp->arg_unset && *pp->arg_unset) + switches = g_list_append (switches, strdup ((char *) pp->arg_unset)); + } + return switches; +} + + +/* Ensures that no switch is mentioned more than once. + */ +static void +sanity_check_parameters (const char *filename, GList *parms) +{ + GList *list = get_all_switches (filename, parms); + GList *p; + for (p = list; p; p = p->next) + { + char *sw = (char *) p->data; + GList *p2; + + if (*sw != '-' && *sw != '+') + fprintf (stderr, "%s: %s: switch does not begin with hyphen \"%s\"\n", + blurb(), filename, sw); + + for (p2 = p->next; p2; p2 = p2->next) + { + const char *sw2 = (const char *) p2->data; + if (!strcmp (sw, sw2)) + fprintf (stderr, "%s: %s: duplicate switch \"%s\"\n", + blurb(), filename, sw); + } + + free (sw); + } + g_list_free (list); +} + + +/* Helper for make_parameters() + */ +static GList * +make_parameters_1 (const char *filename, xmlNodePtr node, GtkWidget *parent) +{ + GList *list = 0; + + for (; node; node = node->next) + { + const char *name = (char *) node->name; + if (!strcmp (name, "hgroup") || + !strcmp (name, "vgroup")) + { + GtkWidget *box = (*name == 'h' + ? gtk_hbox_new (FALSE, 0) + : gtk_vbox_new (FALSE, 0)); + GList *list2; + gtk_widget_show (box); + gtk_box_pack_start (GTK_BOX (parent), box, FALSE, FALSE, 0); + + list2 = make_parameters_1 (filename, node->xmlChildrenNode, box); + if (list2) + list = g_list_concat (list, list2); + } + else + { + parameter *p = make_parameter (filename, node); + if (p) + { + list = g_list_append (list, p); + make_parameter_widget (filename, p, parent); + } + } + } + return list; +} + + +/* Calls make_parameter() and make_parameter_widget() on each relevant + tag in the XML tree. Also handles the "hgroup" and "vgroup" flags. + Returns a GList of `parameter' objects. + */ +static GList * +make_parameters (const char *filename, xmlNodePtr node, GtkWidget *parent) +{ + for (; node; node = node->next) + { + if (node->type == XML_ELEMENT_NODE && + !strcmp ((char *) node->name, "screensaver")) + return make_parameters_1 (filename, node->xmlChildrenNode, parent); + } + return 0; +} + + +static gfloat +invert_range (gfloat low, gfloat high, gfloat value) +{ + gfloat range = high-low; + gfloat off = value-low; + return (low + (range - off)); +} + + +static GtkAdjustment * +make_adjustment (const char *filename, parameter *p) +{ + float range = (p->high - p->low); + float value = (p->invert_p + ? invert_range (p->low, p->high, p->value) + : p->value); + gfloat si = (p->high - p->low) / 100; + gfloat pi = (p->high - p->low) / 10; + gfloat page_size = ((p->type == SLIDER) ? 1 : 0); + + if (p->value < p->low || p->value > p->high) + { + if (debug_p && p->integer_p) + fprintf (stderr, "%s: WARNING: %s: %d is not in range [%d, %d]\n", + blurb(), filename, + (int) p->value, (int) p->low, (int) p->high); + else if (debug_p) + fprintf (stderr, + "%s: WARNING: %s: %.2f is not in range [%.2f, %.2f]\n", + blurb(), filename, p->value, p->low, p->high); + value = (value < p->low ? p->low : p->high); + } +#if 0 + else if (debug_p && p->value < 1000 && p->high >= 10000) + { + if (p->integer_p) + fprintf (stderr, + "%s: WARNING: %s: %d is suspicious for range [%d, %d]\n", + blurb(), filename, + (int) p->value, (int) p->low, (int) p->high); + else + fprintf (stderr, + "%s: WARNING: %s: %.2f is suspicious for range [%.2f, %.2f]\n", + blurb(), filename, p->value, p->low, p->high); + } +#endif /* 0 */ + + si = (int) (si + 0.5); + pi = (int) (pi + 0.5); + if (si < 1) si = 1; + if (pi < 1) pi = 1; + + if (range <= 500) si = 1; + + return GTK_ADJUSTMENT (gtk_adjustment_new (value, + p->low, + p->high + page_size, + si, pi, page_size)); +} + + + +static void +set_widget_min_width (GtkWidget *w, int width) +{ + GtkRequisition req; + gtk_widget_size_request (GTK_WIDGET (w), &req); + if (req.width < width) + gtk_widget_set_size_request (GTK_WIDGET (w), width, -1); +} + + +/* If we're inside a vbox, we need to put an hbox in it, or labels appear + on top instead of to the left, and things stretch to the full width of + the window. + */ +static GtkWidget * +insert_fake_hbox (GtkWidget *parent) +{ + if (GTK_IS_VBOX (parent)) + { + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (parent), hbox, FALSE, FALSE, 4); + gtk_widget_show (hbox); + return hbox; + } + return parent; +} + + +static void +link_atk_label_to_widget(GtkWidget *label, GtkWidget *widget) +{ + AtkObject *atk_label = gtk_widget_get_accessible (label); + AtkObject *atk_widget = gtk_widget_get_accessible (widget); + + atk_object_add_relationship (atk_label, ATK_RELATION_LABEL_FOR, + atk_widget); + atk_object_add_relationship (atk_widget, ATK_RELATION_LABELLED_BY, + atk_label); +} + +/* Given a `parameter' struct, allocates an appropriate GtkWidget for it, + and stores it in `p->widget'. + `parent' must be a GtkBox. + */ +static void +make_parameter_widget (const char *filename, parameter *p, GtkWidget *parent) +{ + const char *label = (char *) p->label; + if (p->widget) return; + + switch (p->type) + { + case STRING: + { + GtkWidget *entry = gtk_entry_new (); + parent = insert_fake_hbox (parent); + if (label) + { + GtkWidget *w = gtk_label_new (_(label)); + link_atk_label_to_widget (w, entry); + gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); + gtk_widget_show (w); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + } + + p->widget = entry; + if (p->string) + gtk_entry_set_text (GTK_ENTRY (p->widget), (char *) p->string); + gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); + break; + } + case FILENAME: + { + GtkWidget *L = gtk_label_new (label ? _(label) : ""); + GtkWidget *entry = gtk_entry_new (); + GtkWidget *button = gtk_button_new_with_label (_("Browse...")); + link_atk_label_to_widget (L, entry); + gtk_widget_show (entry); + gtk_widget_show (button); + p->widget = entry; + + gtk_signal_connect (GTK_OBJECT (button), + "clicked", GTK_SIGNAL_FUNC (browse_button_cb), + (gpointer) entry); + + gtk_label_set_justify (GTK_LABEL (L), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (L), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (L), MIN_LABEL_WIDTH); + gtk_widget_show (L); + + if (p->string) + gtk_entry_set_text (GTK_ENTRY (entry), (char *) p->string); + + parent = insert_fake_hbox (parent); + gtk_box_pack_start (GTK_BOX (parent), L, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), entry, TRUE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (parent), button, FALSE, FALSE, 4); + break; + } + case SLIDER: + { + GtkAdjustment *adj = make_adjustment (filename, p); + GtkWidget *scale = gtk_hscale_new (adj); + GtkWidget *labelw = 0; + + if (label) + { + labelw = gtk_label_new (_(label)); + link_atk_label_to_widget (labelw, scale); + gtk_label_set_justify (GTK_LABEL (labelw), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (labelw), 0.0, 0.5); + set_widget_min_width (GTK_WIDGET (labelw), MIN_LABEL_WIDTH); + gtk_widget_show (labelw); + gtk_box_pack_start (GTK_BOX (parent), labelw, FALSE, FALSE, 2); + } + + /* Do this after 'labelw' so that it appears above, not to left. */ + parent = insert_fake_hbox (parent); + + if (p->low_label) + { + GtkWidget *w = gtk_label_new (_((char *) p->low_label)); + link_atk_label_to_widget (w, scale); + gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); + gtk_widget_show (w); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + } + + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_BOTTOM); + gtk_scale_set_draw_value (GTK_SCALE (scale), debug_p); + gtk_scale_set_digits (GTK_SCALE (scale), (p->integer_p ? 0 : 2)); + set_widget_min_width (GTK_WIDGET (scale), MIN_SLIDER_WIDTH); + + gtk_box_pack_start (GTK_BOX (parent), scale, FALSE, FALSE, 4); + + gtk_widget_show (scale); + + if (p->high_label) + { + GtkWidget *w = gtk_label_new (_((char *) p->high_label)); + link_atk_label_to_widget (w, scale); + gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); + gtk_widget_show (w); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + } + + p->widget = scale; + break; + } + case SPINBUTTON: + { + GtkAdjustment *adj = make_adjustment (filename, p); + GtkWidget *spin = gtk_spin_button_new (adj, 15, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (spin), TRUE); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), GET_ADJ_VALUE(adj)); + set_widget_min_width (GTK_WIDGET (spin), MIN_SPINBUTTON_WIDTH); + + if (label) + { + GtkWidget *w = gtk_label_new (_(label)); + link_atk_label_to_widget (w, spin); + gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); + gtk_widget_show (w); + parent = insert_fake_hbox (parent); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + } + + gtk_widget_show (spin); + gtk_box_pack_start (GTK_BOX (parent), spin, FALSE, FALSE, 4); + + p->widget = spin; + break; + } + case BOOLEAN: + { + p->widget = gtk_check_button_new_with_label (_(label)); + /* Let these stretch -- doesn't hurt. + parent = insert_fake_hbox (parent); + */ + gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); + break; + } + case SELECT: + { + GtkWidget *opt = gtk_option_menu_new (); + GtkWidget *menu = gtk_menu_new (); + GList *opts; + + for (opts = p->options; opts; opts = opts->next) + { + parameter *s = (parameter *) opts->data; + GtkWidget *i = gtk_menu_item_new_with_label (_((char *) s->label)); + gtk_widget_show (i); + gtk_menu_append (GTK_MENU (menu), i); + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu); + p->widget = opt; + parent = insert_fake_hbox (parent); + gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); + break; + } + + case COMMAND: + case FAKE: + case DESCRIPTION: + case FAKEPREVIEW: + break; + default: + abort(); + } + + if (p->widget) + { + gtk_widget_set_name (p->widget, (char *) p->id); + gtk_widget_show (p->widget); + } +} + + +/* File selection. + Absurdly, there is no GTK file entry widget, only a GNOME one, + so in order to avoid depending on GNOME in this code, we have + to do it ourselves. + */ + +/* cancel button on GtkFileSelection: user_data unused */ +static void +file_sel_cancel (GtkWidget *button, gpointer user_data) +{ + GtkWidget *dialog = button; + while (GET_PARENT (dialog)) + dialog = GET_PARENT (dialog); + gtk_widget_destroy (dialog); +} + +/* ok button on GtkFileSelection: user_data is the corresponding GtkEntry */ +static void +file_sel_ok (GtkWidget *button, gpointer user_data) +{ + GtkWidget *entry = GTK_WIDGET (user_data); + GtkWidget *dialog = button; + const char *path; + + while (GET_PARENT (dialog)) + dialog = GET_PARENT (dialog); + gtk_widget_hide (dialog); + + path = gtk_file_selection_get_filename (GTK_FILE_SELECTION (dialog)); + /* apparently one doesn't free `path' */ + + gtk_entry_set_text (GTK_ENTRY (entry), path); + gtk_entry_set_position (GTK_ENTRY (entry), strlen (path)); + + gtk_widget_destroy (dialog); +} + +/* WM close on GtkFileSelection: user_data unused */ +static void +file_sel_close (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + file_sel_cancel (widget, user_data); +} + +/* "Browse" button: user_data is the corresponding GtkEntry */ +static void +browse_button_cb (GtkButton *button, gpointer user_data) +{ + GtkWidget *entry = GTK_WIDGET (user_data); + const char *text = gtk_entry_get_text (GTK_ENTRY (entry)); + GtkFileSelection *selector = + GTK_FILE_SELECTION (gtk_file_selection_new (_("Select file."))); + + gtk_file_selection_set_filename (selector, text); + gtk_signal_connect (GTK_OBJECT (selector->ok_button), + "clicked", GTK_SIGNAL_FUNC (file_sel_ok), + (gpointer) entry); + gtk_signal_connect (GTK_OBJECT (selector->cancel_button), + "clicked", GTK_SIGNAL_FUNC (file_sel_cancel), + (gpointer) entry); + gtk_signal_connect (GTK_OBJECT (selector), "delete_event", + GTK_SIGNAL_FUNC (file_sel_close), + (gpointer) entry); + + gtk_window_set_modal (GTK_WINDOW (selector), TRUE); + gtk_widget_show (GTK_WIDGET (selector)); +} + + +/* Converting to and from command-lines + */ + + +/* Returns a copy of string that has been quoted according to shell rules: + it may have been wrapped in "" and had some characters backslashed; or + it may be unchanged. + */ +static char * +shell_quotify (const char *string) +{ + char *string2 = (char *) malloc ((strlen (string) * 2) + 10); + const char *in; + char *out; + int need_quotes = 0; + int in_length = 0; + + out = string2; + *out++ = '"'; + for (in = string; *in; in++) + { + in_length++; + if (*in == '!' || + *in == '"' || + *in == '$') + { + need_quotes = 1; + *out++ = '\\'; + *out++ = *in; + } + else if (*in <= ' ' || + *in >= 127 || + *in == '\'' || + *in == '#' || + *in == '%' || + *in == '&' || + *in == '(' || + *in == ')' || + *in == '*') + { + need_quotes = 1; + *out++ = *in; + } + else + *out++ = *in; + } + *out++ = '"'; + *out = 0; + + if (in_length == 0) + need_quotes = 1; + + if (need_quotes) + return (string2); + + free (string2); + return strdup (string); +} + +/* Modify the string in place to remove wrapping double-quotes + and interior backslashes. + */ +static void +de_stringify (char *s) +{ + char q = s[0]; + if (q != '\'' && q != '\"' && q != '`') + abort(); + memmove (s, s+1, strlen (s)+1); + while (*s && *s != q) + { + if (*s == '\\') + memmove (s, s+1, strlen (s)+1); + s++; + } + if (*s != q) abort(); + *s = 0; +} + + +/* Substitutes a shell-quotified version of `value' into `p->arg' at + the place where the `%' character appeared. + */ +static char * +format_switch (parameter *p, const char *value) +{ + char *fmt = (char *) p->arg; + char *v2; + char *result, *s; + if (!fmt || !value) return 0; + v2 = shell_quotify (value); + result = (char *) malloc (strlen (fmt) + strlen (v2) + 10); + s = result; + for (; *fmt; fmt++) + if (*fmt != '%') + *s++ = *fmt; + else + { + strcpy (s, v2); + s += strlen (s); + } + *s = 0; + + free (v2); + return result; +} + + +/* Maps a `parameter' to a command-line switch. + Returns 0 if it can't, or if the parameter has the default value. + */ +static char * +parameter_to_switch (parameter *p) +{ + switch (p->type) + { + case COMMAND: + if (p->arg) + return strdup ((char *) p->arg); + else + return 0; + break; + case STRING: + case FILENAME: + if (!p->widget) return 0; + { + const char *s = gtk_entry_get_text (GTK_ENTRY (p->widget)); + char *v; + if (!strcmp ((s ? s : ""), + (p->string ? (char *) p->string : ""))) + v = 0; /* same as default */ + else + v = format_switch (p, s); + + /* don't free `s' */ + return v; + } + case SLIDER: + case SPINBUTTON: + if (!p->widget) return 0; + { + GtkAdjustment *adj = + (p->type == SLIDER + ? gtk_range_get_adjustment (GTK_RANGE (p->widget)) + : gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (p->widget))); + char buf[255]; + char *s1; + float value = (p->invert_p + ? invert_range (GET_ADJ_LOWER(adj), GET_ADJ_UPPER(adj), + GET_ADJ_VALUE(adj)) - 1 + : GET_ADJ_VALUE(adj)); + + if (value == p->value) /* same as default */ + return 0; + + if (p->integer_p) + sprintf (buf, "%d", (int) (value + (value > 0 ? 0.5 : -0.5))); + else + sprintf (buf, "%.4f", value); + + s1 = strchr (buf, '.'); + if (s1) + { + char *s2 = s1 + strlen(s1) - 1; + while (s2 > s1 && *s2 == '0') /* lose trailing zeroes */ + *s2-- = 0; + if (s2 >= s1 && *s2 == '.') /* lose trailing decimal */ + *s2-- = 0; + } + return format_switch (p, buf); + } + case BOOLEAN: + if (!p->widget) return 0; + { + GtkToggleButton *b = GTK_TOGGLE_BUTTON (p->widget); + const char *s = (gtk_toggle_button_get_active (b) + ? (char *) p->arg_set + : (char *) p->arg_unset); + if (s) + return strdup (s); + else + return 0; + } + case SELECT: + if (!p->widget) return 0; + { + GtkOptionMenu *opt = GTK_OPTION_MENU (p->widget); + GtkMenu *menu = GTK_MENU (gtk_option_menu_get_menu (opt)); + GtkWidget *selected = gtk_menu_get_active (menu); + GList *kids = gtk_container_children (GTK_CONTAINER (menu)); + int menu_elt = g_list_index (kids, (gpointer) selected); + GList *ol = g_list_nth (p->options, menu_elt); + parameter *o = (ol ? (parameter *) ol->data : 0); + const char *s; + if (!o) abort(); + if (o->type != SELECT_OPTION) abort(); + s = (char *) o->arg_set; + if (s) + return strdup (s); + else + return 0; + } + default: + if (p->widget) + abort(); + else + return 0; + } +} + +/* Maps a GList of `parameter' objects to a complete command-line string. + All arguments will be properly quoted. + */ +static char * +parameters_to_cmd_line (GList *parms, gboolean default_p) +{ + int L = g_list_length (parms); + int LL = 0; + char **strs = (char **) calloc (sizeof (*parms), L); + char *result; + char *out; + int i, j; + + for (i = 0, j = 0; parms; parms = parms->next, i++) + { + parameter *p = (parameter *) parms->data; + if (!default_p || p->type == COMMAND) + { + char *s = parameter_to_switch (p); + strs[j++] = s; + LL += (s ? strlen(s) : 0) + 1; + } + } + + result = (char *) malloc (LL + 10); + out = result; + for (i = 0; i < j; i++) + if (strs[i]) + { + strcpy (out, strs[i]); + out += strlen (out); + *out++ = ' '; + free (strs[i]); + } + *out = 0; + while (out > result && out[-1] == ' ') /* strip trailing spaces */ + *(--out) = 0; + free (strs); + + return result; +} + + +/* Returns a GList of the tokens the string, using shell syntax; + Quoted strings are handled as a single token. + */ +static GList * +tokenize_command_line (const char *cmd) +{ + GList *result = 0; + const char *s = cmd; + while (*s) + { + const char *start; + char *ss; + for (; isspace(*s); s++); /* skip whitespace */ + + start = s; + if (*s == '\'' || *s == '\"' || *s == '`') + { + char q = *s; + s++; + while (*s && *s != q) /* skip to matching quote */ + { + if (*s == '\\' && s[1]) /* allowing backslash quoting */ + s++; + s++; + } + s++; + } + else + { + while (*s && + (! (isspace(*s) || + *s == '\'' || + *s == '\"' || + *s == '`'))) + s++; + } + + if (s > start) + { + ss = (char *) malloc ((s - start) + 1); + strncpy (ss, start, s-start); + ss[s-start] = 0; + if (*ss == '\'' || *ss == '\"' || *ss == '`') + de_stringify (ss); + result = g_list_append (result, ss); + } + } + + return result; +} + +static void parameter_set_switch (parameter *, gpointer value); +static gboolean parse_command_line_into_parameters_1 (const char *filename, + GList *parms, + const char *option, + const char *value, + parameter *parent); + + +/* Parses the command line, and flushes those options down into + the `parameter' structs in the list. + */ +static void +parse_command_line_into_parameters (const char *filename, + const char *cmd, GList *parms) +{ + GList *tokens = tokenize_command_line (cmd); + GList *rest; + for (rest = tokens; rest; rest = rest->next) + { + char *option = rest->data; + rest->data = 0; + + if (option[0] != '-' && option[0] != '+') + { + if (debug_p) + fprintf (stderr, "%s: WARNING: %s: not a switch: \"%s\"\n", + blurb(), filename, option); + } + else + { + char *value = 0; + + if (rest->next) /* pop off the arg to this option */ + { + char *s = (char *) rest->next->data; + /* the next token is the next switch iff it matches "-[a-z]". + (To avoid losing on "-x -3.1".) + */ + if (s && (s[0] != '-' || !isalpha(s[1]))) + { + value = s; + rest->next->data = 0; + rest = rest->next; + } + } + + parse_command_line_into_parameters_1 (filename, parms, + option, value, 0); + if (value) free (value); + free (option); + } + } + g_list_free (tokens); +} + + +static gboolean +compare_opts (const char *option, const char *value, + const char *template) +{ + int ol = strlen (option); + char *c; + + if (strncmp (option, template, ol)) + return FALSE; + + if (template[ol] != (value ? ' ' : 0)) + return FALSE; + + /* At this point, we have a match against "option". + If template contains a %, we're done. + Else, compare against "value" too. + */ + c = strchr (template, '%'); + if (c) + return TRUE; + + if (!value) + return (template[ol] == 0); + if (strcmp (template + ol + 1, value)) + return FALSE; + + return TRUE; +} + + +static gboolean +parse_command_line_into_parameters_1 (const char *filename, + GList *parms, + const char *option, + const char *value, + parameter *parent) +{ + GList *p; + parameter *match = 0; + gint which = -1; + gint index = 0; + + for (p = parms; p; p = p->next) + { + parameter *pp = (parameter *) p->data; + which = -99; + + if (pp->type == SELECT) + { + if (parse_command_line_into_parameters_1 (filename, + pp->options, + option, value, + pp)) + { + which = -2; + match = pp; + } + } + else if (pp->arg) + { + if (compare_opts (option, value, (char *) pp->arg)) + { + which = -1; + match = pp; + } + } + else if (pp->arg_set) + { + if (compare_opts (option, value, (char *) pp->arg_set)) + { + which = 1; + match = pp; + } + } + else if (pp->arg_unset) + { + if (compare_opts (option, value, (char *) pp->arg_unset)) + { + which = 0; + match = pp; + } + } + + if (match) + break; + + index++; + } + + if (!match) + { + if (debug_p && !parent) + fprintf (stderr, "%s: WARNING: %s: no match for %s %s\n", + blurb(), filename, option, (value ? value : "")); + return FALSE; + } + + switch (match->type) + { + case STRING: + case FILENAME: + case SLIDER: + case SPINBUTTON: + if (which != -1) abort(); + parameter_set_switch (match, (gpointer) value); + break; + case BOOLEAN: + if (which != 0 && which != 1) abort(); + parameter_set_switch (match, GINT_TO_POINTER(which)); + break; + case SELECT_OPTION: + if (which != 1) abort(); + parameter_set_switch (parent, GINT_TO_POINTER(index)); + break; + default: + break; + } + return TRUE; +} + + +/* Set the parameter's value. + For STRING, FILENAME, SLIDER, and SPINBUTTON, `value' is a char*. + For BOOLEAN and SELECT, `value' is an int. + */ +static void +parameter_set_switch (parameter *p, gpointer value) +{ + if (p->type == SELECT_OPTION) abort(); + if (!p->widget) return; + switch (p->type) + { + case STRING: + case FILENAME: + { + gtk_entry_set_text (GTK_ENTRY (p->widget), (char *) value); + break; + } + case SLIDER: + case SPINBUTTON: + { + GtkAdjustment *adj = + (p->type == SLIDER + ? gtk_range_get_adjustment (GTK_RANGE (p->widget)) + : gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (p->widget))); + float f; + char c; + + if (1 == sscanf ((char *) value, "%f %c", &f, &c)) + { + if (p->invert_p) + f = invert_range (GET_ADJ_LOWER(adj), GET_ADJ_UPPER(adj), f) - 1; + gtk_adjustment_set_value (adj, f); + } + break; + } + case BOOLEAN: + { + GtkToggleButton *b = GTK_TOGGLE_BUTTON (p->widget); + gtk_toggle_button_set_active (b, GPOINTER_TO_INT(value)); + break; + } + case SELECT: + { + gtk_option_menu_set_history (GTK_OPTION_MENU (p->widget), + GPOINTER_TO_INT(value)); + break; + } + default: + abort(); + } +} + + +static void +restore_defaults (const char *progname, GList *parms) +{ + for (; parms; parms = parms->next) + { + parameter *p = (parameter *) parms->data; + if (!p->widget) continue; + switch (p->type) + { + case STRING: + case FILENAME: + { + gtk_entry_set_text (GTK_ENTRY (p->widget), + (p->string ? (char *) p->string : "")); + break; + } + case SLIDER: + case SPINBUTTON: + { + GtkAdjustment *adj = + (p->type == SLIDER + ? gtk_range_get_adjustment (GTK_RANGE (p->widget)) + : gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (p->widget))); + float value = (p->invert_p + ? invert_range (p->low, p->high, p->value) + : p->value); + gtk_adjustment_set_value (adj, value); + break; + } + case BOOLEAN: + { + /* A toggle button should be on by default if it inserts + nothing into the command line when on. E.g., it should + be on if `arg_set' is null. + */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p->widget), + (!p->arg_set || !*p->arg_set)); + break; + } + case SELECT: + { + GtkOptionMenu *opt = GTK_OPTION_MENU (p->widget); + GList *opts; + int selected = 0; + int index; + + for (opts = p->options, index = 0; opts; + opts = opts->next, index++) + { + parameter *s = (parameter *) opts->data; + /* The default menu item is the first one with + no `arg_set' field. */ + if (!s->arg_set) + { + selected = index; + break; + } + } + + gtk_option_menu_set_history (GTK_OPTION_MENU (opt), selected); + break; + } + default: + abort(); + } + } +} + + + +/* Documentation strings + */ + +static char * +get_description (GList *parms, gboolean verbose_p) +{ + parameter *doc = 0; + for (; parms; parms = parms->next) + { + parameter *p = (parameter *) parms->data; + if (p->type == DESCRIPTION) + { + doc = p; + break; + } + } + + if (!doc || !doc->string) + return 0; + else + { + char *d = strdup ((char *) doc->string); + char *s; + char *p; + for (s = d; *s; s++) + if (s[0] == '\n') + { + if (s[1] == '\n') /* blank line: leave it */ + s++; + else if (s[1] == ' ' || s[1] == '\t') + s++; /* next line is indented: leave newline */ + else if (!strncmp(s+1, "http:", 5)) + s++; /* next line begins a URL: leave newline */ + else + s[0] = ' '; /* delete newline to un-fold this line */ + } + + /* strip off leading whitespace on first line only */ + for (s = d; *s && (*s == ' ' || *s == '\t'); s++) + ; + while (*s == '\n') /* strip leading newlines */ + s++; + if (s != d) + memmove (d, s, strlen(s)+1); + + /* strip off trailing whitespace and newlines */ + { + int L = strlen(d); + while (L && isspace(d[L-1])) + d[--L] = 0; + } + + /* strip off duplicated whitespaces */ + for (s = d; *s; s++) + if (s[0] == ' ') + { + p = s+1; + while (*s == ' ') + s++; + if (*p && (s != p)) + memmove (p, s, strlen(s)+1); + } + +#if 0 + if (verbose_p) + { + fprintf (stderr, "%s: text read is \"%s\"\n", blurb(),doc->string); + fprintf (stderr, "%s: description is \"%s\"\n", blurb(), d); + fprintf (stderr, "%s: translation is \"%s\"\n", blurb(), _(d)); + } +#endif /* 0 */ + + return (d); + } +} + + +/* External interface. + */ + +static conf_data * +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; + FILE *f; + conf_data *data; + + if (L == 0) return 0; + + 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, base_program); + + for (s = file+L; *s; s++) + if (*s == '/' || *s == ' ') + *s = '_'; + else if (isupper (*s)) + *s = tolower (*s); + + strcat (file+L, ".xml"); + + f = fopen (file, "r"); + if (f) + { + int res, size = 1024; + char chars[1024]; + xmlParserCtxtPtr ctxt; + xmlDocPtr doc = 0; + GtkWidget *vbox0; + GList *parms; + + if (verbose_p) + fprintf (stderr, "%s: reading %s...\n", blurb(), file); + + res = fread (chars, 1, 4, f); + if (res <= 0) + { + free (data); + data = 0; + goto DONE; + } + + ctxt = xmlCreatePushParserCtxt(NULL, NULL, chars, res, file); + while ((res = fread(chars, 1, size, f)) > 0) + xmlParseChunk (ctxt, chars, res, 0); + xmlParseChunk (ctxt, chars, 0, 1); + doc = ctxt->myDoc; + xmlFreeParserCtxt (ctxt); + fclose (f); + + /* Parsed the XML file. Now make some widgets. */ + + vbox0 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox0); + + parms = make_parameters (file, doc->xmlRootNode, vbox0); + sanity_check_parameters (file, parms); + + xmlFreeDoc (doc); + + restore_defaults (program, parms); + if (arguments && *arguments) + parse_command_line_into_parameters (program, arguments, parms); + + data->widget = vbox0; + data->parameters = parms; + data->description = get_description (parms, verbose_p); + } + else + { + parameter *p; + + if (verbose_p) + fprintf (stderr, "%s: %s does not exist.\n", blurb(), file); + + p = calloc (1, sizeof(*p)); + p->type = COMMAND; + p->arg = (xmlChar *) strdup (arguments); + + data->parameters = g_list_append (0, (gpointer) p); + } + + data->progname = strdup (program); + + DONE: + free (file); + return data; +} + +static void +split_command_line (const char *full_command_line, + char **prog_ret, char **args_ret) +{ + char *line = strdup (full_command_line); + char *prog; + char *args; + char *s; + + prog = line; + s = line; + while (*s) + { + if (isspace (*s)) + { + *s = 0; + s++; + while (isspace (*s)) s++; + break; + } + else if (*s == '=') /* if the leading word contains an "=", skip it. */ + { + while (*s && !isspace (*s)) s++; + while (isspace (*s)) s++; + prog = s; + } + s++; + } + args = s; + + *prog_ret = strdup (prog); + *args_ret = strdup (args); + free (line); +} + + +conf_data * +load_configurator (const char *full_command_line, gboolean verbose_p) +{ + char *prog; + char *args; + conf_data *cd; + debug_p = verbose_p; + split_command_line (full_command_line, &prog, &args); + cd = load_configurator_1 (prog, args, verbose_p); + free (prog); + free (args); + return cd; +} + + + +char * +get_configurator_command_line (conf_data *data, gboolean default_p) +{ + char *args = parameters_to_cmd_line (data->parameters, default_p); + char *result = (char *) malloc (strlen (data->progname) + + strlen (args) + 2); + strcpy (result, data->progname); + strcat (result, " "); + strcat (result, args); + free (args); + return result; +} + + +void +set_configurator_command_line (conf_data *data, const char *full_command_line) +{ + char *prog; + char *args; + split_command_line (full_command_line, &prog, &args); + if (data->progname) free (data->progname); + data->progname = prog; + restore_defaults (prog, data->parameters); + parse_command_line_into_parameters (prog, args, data->parameters); + free (args); +} + +void +free_conf_data (conf_data *data) +{ + if (data->parameters) + { + GList *rest; + for (rest = data->parameters; rest; rest = rest->next) + { + free_parameter ((parameter *) rest->data); + rest->data = 0; + } + g_list_free (data->parameters); + data->parameters = 0; + } + + if (data->widget) + gtk_widget_destroy (data->widget); + + if (data->progname) + free (data->progname); + if (data->description) + free (data->description); + + memset (data, ~0, sizeof(*data)); + free (data); +} + + +#endif /* HAVE_GTK && HAVE_XML -- whole file */ diff --git a/driver/demo-Gtk-conf.h b/driver/demo-Gtk-conf.h new file mode 100644 index 00000000..f462152c --- /dev/null +++ b/driver/demo-Gtk-conf.h @@ -0,0 +1,31 @@ +/* demo-Gtk-conf.c --- implements the dynamic configuration dialogs. + * xscreensaver, Copyright (c) 2001-2008 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 _DEMO_GTK_CONF_H_ +#define _DEMO_GTK_CONF_H_ + +typedef struct { + GtkWidget *widget; /* the container widget with the sliders and stuff. */ + GList *parameters; /* internal data -- hands off */ + char *progname; + char *progclass; + char *description; +} conf_data; + +extern conf_data *load_configurator (const char *cmd_line, gboolean verbose_p); +extern char *get_configurator_command_line (conf_data *, gboolean default_p); +extern void set_configurator_command_line (conf_data *, const char *cmd_line); +extern void free_conf_data (conf_data *); + +extern const char *hack_configuration_path; + +#endif /* _DEMO_GTK_CONF_H_ */ diff --git a/driver/demo-Gtk-stubs.h b/driver/demo-Gtk-stubs.h new file mode 100644 index 00000000..c897d3ed --- /dev/null +++ b/driver/demo-Gtk-stubs.h @@ -0,0 +1,90 @@ +#include + + +void +activate_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +lock_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +kill_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +restart_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +exit_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +about_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +doc_menu_cb (GtkMenuItem *menuitem, + gpointer user_data); + +void +switch_page_cb (GtkNotebook *notebook, + GtkNotebookPage *page, + gint page_num, + gpointer user_data); + +void +pref_changed_cb (GtkToggleButton *togglebutton, + gpointer user_data); + +void +run_this_cb (GtkButton *button, + gpointer user_data); + +void +settings_cb (GtkButton *button, + gpointer user_data); + +void +run_next_cb (GtkButton *button, + gpointer user_data); + +void +run_prev_cb (GtkButton *button, + gpointer user_data); + +void +browse_image_dir_cb (GtkButton *button, + gpointer user_data); + +void +settings_switch_page_cb (GtkNotebook *notebook, + GtkNotebookPage *page, + gint page_num, + gpointer user_data); + +void +manual_cb (GtkButton *button, + gpointer user_data); + +void +settings_adv_cb (GtkButton *button, + gpointer user_data); + +void +settings_std_cb (GtkButton *button, + gpointer user_data); + +void +settings_reset_cb (GtkButton *button, + gpointer user_data); + +void +settings_ok_cb (GtkButton *button, + gpointer user_data); + +void +settings_cancel_cb (GtkButton *button, + gpointer user_data); diff --git a/driver/demo-Gtk-support.c b/driver/demo-Gtk-support.c new file mode 100644 index 00000000..881129c4 --- /dev/null +++ b/driver/demo-Gtk-support.c @@ -0,0 +1,219 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + WARNING: I did edit this file! Be careful! -jwz + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include + +#include "demo-Gtk-support.h" + +/* jwz -- dumbass Glade1 doesn't emit code that can read PNGs. this does. */ +#ifdef HAVE_GDK_PIXBUF +# ifdef HAVE_GTK2 +# include +# else /* !HAVE_GTK2 */ +# include +# endif /* !HAVE_GTK2 */ +#endif /* HAVE_GDK_PIXBUF */ + + +/* This is an internally used function to check if a pixmap file exists. */ +static gchar* check_file_exists (const gchar *directory, + const gchar *filename); + +/* This is an internally used function to create pixmaps. */ +static GtkWidget* create_dummy_pixmap (GtkWidget *widget); + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +/* This is a dummy pixmap we use when a pixmap can't be found. */ +static char *dummy_pixmap_xpm[] = { +/* columns rows colors chars-per-pixel */ +"1 1 1 1", +" c None", +/* pixels */ +" " +}; + +/* This is an internally used function to create pixmaps. */ +static GtkWidget* +create_dummy_pixmap (GtkWidget *widget) +{ + GdkColormap *colormap; + GdkPixmap *gdkpixmap; + GdkBitmap *mask; + GtkWidget *pixmap; + + colormap = gtk_widget_get_colormap (widget); + gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask, + NULL, dummy_pixmap_xpm); + if (gdkpixmap == NULL) + g_error ("Couldn't create replacement pixmap."); + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gdk_pixmap_unref (gdkpixmap); + gdk_bitmap_unref (mask); + return pixmap; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to create pixmaps. */ +/* #### Warning: this version of this function hacked by jwz to + support PNGs. Don't let Glade1 overwrite this! + */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *found_filename = NULL; + GdkColormap *colormap = 0; + GdkPixmap *gdkpixmap = 0; + GdkBitmap *mask = 0; + GtkWidget *pixmap = 0; + GList *elem = 0; + + if (!filename || !filename[0]) + return create_dummy_pixmap (widget); + + /* We first try any pixmaps directories set by the application. */ + elem = pixmaps_directories; + while (elem) + { + found_filename = check_file_exists ((gchar*)elem->data, filename); + if (found_filename) + break; + elem = elem->next; + } + + /* If we haven't found the pixmap, try the source directory. */ + if (!found_filename) + { + found_filename = check_file_exists ("../utils/images", filename); + } + + if (!found_filename) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return create_dummy_pixmap (widget); + } + + colormap = gtk_widget_get_colormap (widget); + +# ifndef HAVE_GDK_PIXBUF + + gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask, + NULL, found_filename); + if (gdkpixmap == NULL) + { + g_warning (_("Error loading pixmap file: %s"), found_filename); + g_free (found_filename); + return create_dummy_pixmap (widget); + } + +# else /* HAVE_GDK_PIXBUF */ + + /* jwz -- dumbass Glade1 doesn't emit code that can read PNGs. + This code does... */ + + /* #### Danger: we aren't using `colormap'... */ + + { + GdkPixbuf *pb; +# ifdef HAVE_GTK2 + GError *gerr = 0; +# endif /* HAVE_GTK2 */ + + pb = gdk_pixbuf_new_from_file (found_filename +# ifdef HAVE_GTK2 + , &gerr +# endif /* HAVE_GTK2 */ + ); + + if (pb) + { + gdkpixmap = 0; + mask = 0; + gdk_pixbuf_render_pixmap_and_mask (pb, &gdkpixmap, &mask, 128); + } + else + { + g_warning (_("Error loading pixmap file: %s"), found_filename); +# ifdef HAVE_GTK2 + if (gerr && gerr->message && *gerr->message) + g_warning (_("reason: %s\n"), gerr->message); +# endif /* HAVE_GTK2 */ + + return create_dummy_pixmap (widget); + } + } +# endif /* HAVE_GDK_PIXBUF */ + + g_free (found_filename); + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gdk_pixmap_unref (gdkpixmap); + gdk_bitmap_unref (mask); + + return pixmap; +} + +/* This is an internally used function to check if a pixmap file exists. */ +static gchar* +check_file_exists (const gchar *directory, + const gchar *filename) +{ + gchar *full_filename; + struct stat s; + gint status; + + full_filename = (gchar*) g_malloc (strlen (directory) + 1 + + strlen (filename) + 1); + strcpy (full_filename, directory); + strcat (full_filename, G_DIR_SEPARATOR_S); + strcat (full_filename, filename); + + status = stat (full_filename, &s); + if (status == 0 && S_ISREG (s.st_mode)) + return full_filename; + g_free (full_filename); + return NULL; +} + diff --git a/driver/demo-Gtk-support.h b/driver/demo-Gtk-support.h new file mode 100644 index 00000000..931bc5ad --- /dev/null +++ b/driver/demo-Gtk-support.h @@ -0,0 +1,61 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + +/* get_widget() is deprecated. Use lookup_widget instead. */ +#define get_widget lookup_widget + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + diff --git a/driver/demo-Gtk-widgets.c b/driver/demo-Gtk-widgets.c new file mode 100644 index 00000000..4e853c99 --- /dev/null +++ b/driver/demo-Gtk-widgets.c @@ -0,0 +1,1764 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include + +#include "demo-Gtk-stubs.h" +#include "demo-Gtk-widgets.h" +#include "demo-Gtk-support.h" + +# ifdef __GNUC__ +# define STFU __extension__ /* ignore gcc -pendantic warnings in next sexp */ +# else +# define STFU /* */ +# endif + +GtkWidget* +create_xscreensaver_demo (void) +{ + GtkWidget *xscreensaver_demo; + GtkWidget *outer_vbox; + GtkWidget *menubar; + guint tmp_key; + GtkWidget *file; + GtkWidget *file_menu; + GtkAccelGroup *file_menu_accels; + GtkWidget *activate_menu; + GtkWidget *lock_menu; + GtkWidget *kill_menu; + GtkWidget *restart; + GtkWidget *separator1; + GtkWidget *exit_menu; + GtkWidget *help; + GtkWidget *help_menu; + GtkAccelGroup *help_menu_accels; + GtkWidget *about_menu; + GtkWidget *doc_menu; + GtkWidget *notebook; + GtkWidget *demos_table; + GtkWidget *blanking_table; + GtkWidget *cycle_label; + GtkWidget *lock_button_eventbox; + GtkWidget *lock_button; + GtkWidget *timeout_label; + GtkObject *timeout_spinbutton_adj; + GtkWidget *timeout_spinbutton; + GtkWidget *timeout_mlabel; + GtkWidget *cycle_mlabel; + GtkWidget *lock_mlabel; + GtkObject *lock_spinbutton_adj; + GtkWidget *lock_spinbutton; + GtkObject *cycle_spinbutton_adj; + GtkWidget *cycle_spinbutton; + GtkWidget *demo_manual_hbbox; + GtkWidget *demo; + GtkWidget *settings; + GtkWidget *list_vbox; + GtkWidget *mode_hbox; + GtkWidget *mode_label; + GtkWidget *mode_menu; + GtkWidget *mode_menu_menu; + GtkWidget *glade_menuitem; + GtkWidget *col_head_hbox; + GtkWidget *use_col_frame; + GtkWidget *use_label; + GtkWidget *saver_col_frame; + GtkWidget *saver_label; + GtkWidget *scroller; + GtkWidget *viewport; + GtkWidget *list; + GtkWidget *centering_hbox; + GtkWidget *next_prev_hbox; + GtkWidget *next; + GtkWidget *prev; + GtkWidget *preview_frame; + GtkWidget *preview_aspectframe; + GtkWidget *preview; + GtkWidget *demo_tab; + GtkWidget *options_table; + GtkWidget *diag_frame; + GtkWidget *diag_hbox; + GtkWidget *diag_logo; + GtkWidget *diag_vbox; + GtkWidget *verbose_button_eventbox; + GtkWidget *verbose_button; + GtkWidget *capture_button_eventbox; + GtkWidget *capture_button; + GtkWidget *splash_button_eventbox; + GtkWidget *splash_button; + GtkWidget *cmap_frame; + GtkWidget *cmap_hbox; + GtkWidget *cmap_logo; + GtkWidget *cmap_vbox; + GtkWidget *install_button_eventbox; + GtkWidget *install_button; + GtkWidget *cmap_hr; + GtkWidget *fade_button_eventbox; + GtkWidget *fade_button; + GtkWidget *unfade_button_eventbox; + GtkWidget *unfade_button; + GtkWidget *fade_hbox; + GtkWidget *fade_dummy; + GtkWidget *fade_label; + GtkObject *fade_spinbutton_adj; + GtkWidget *fade_spinbutton; + GtkWidget *fade_sec_label; + GtkWidget *dpms_frame; + GtkWidget *dpms_hbox; + GtkWidget *dpms_logo; + GtkWidget *dpms_vbox; + GtkWidget *dpms_button_eventbox; + GtkWidget *dpms_button; + GtkWidget *dpms_table; + GtkObject *dpms_standby_spinbutton_adj; + GtkWidget *dpms_standby_spinbutton; + GtkWidget *dpms_standby_mlabel; + GtkWidget *dpms_suspend_mlabel; + GtkWidget *dpms_off_mlabel; + GtkWidget *dpms_off_label; + GtkWidget *dpms_suspend_label; + GtkWidget *dpms_standby_label; + GtkObject *dpms_suspend_spinbutton_adj; + GtkWidget *dpms_suspend_spinbutton; + GtkObject *dpms_off_spinbutton_adj; + GtkWidget *dpms_off_spinbutton; + GtkWidget *grab_frame; + GtkWidget *grab_hbox; + GtkWidget *img_logo; + GtkWidget *grab_vbox; + GtkWidget *grab_desk_eventbox; + GtkWidget *grab_desk_button; + GtkWidget *grab_video_eventbox; + GtkWidget *grab_video_button; + GtkWidget *grab_image_eventbox; + GtkWidget *grab_image_button; + GtkWidget *image_hbox; + GtkWidget *grab_dummy; + GtkWidget *image_text; + GtkWidget *image_browse_button; + GtkWidget *options_tab; + GtkAccelGroup *accel_group; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + accel_group = gtk_accel_group_new (); + + xscreensaver_demo = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (xscreensaver_demo, "xscreensaver_demo"); + gtk_object_set_data (GTK_OBJECT (xscreensaver_demo), "xscreensaver_demo", xscreensaver_demo); + gtk_window_set_title (GTK_WINDOW (xscreensaver_demo), _("XScreenSaver")); + gtk_window_set_wmclass (GTK_WINDOW (xscreensaver_demo), "xscreensaver", "XScreenSaver"); + + outer_vbox = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (outer_vbox, "outer_vbox"); + gtk_widget_ref (outer_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "outer_vbox", outer_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (outer_vbox); + gtk_container_add (GTK_CONTAINER (xscreensaver_demo), outer_vbox); + + menubar = gtk_menu_bar_new (); + gtk_widget_set_name (menubar, "menubar"); + gtk_widget_ref (menubar); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "menubar", menubar, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (menubar); + gtk_box_pack_start (GTK_BOX (outer_vbox), menubar, FALSE, FALSE, 0); + + file = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file)->child), + _("_File")); + gtk_widget_add_accelerator (file, "activate_item", accel_group, + tmp_key, GDK_MOD1_MASK, (GtkAccelFlags) 0); + gtk_widget_set_name (file, "file"); + gtk_widget_ref (file); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "file", file, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (file); + gtk_container_add (GTK_CONTAINER (menubar), file); + + file_menu = gtk_menu_new (); + gtk_widget_set_name (file_menu, "file_menu"); + gtk_widget_ref (file_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "file_menu", file_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (file), file_menu); + file_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file_menu)); + + activate_menu = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (activate_menu)->child), + _("_Blank Screen Now")); + gtk_widget_add_accelerator (activate_menu, "activate_item", file_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (activate_menu, "activate_menu"); + gtk_widget_ref (activate_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "activate_menu", activate_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (activate_menu); + gtk_container_add (GTK_CONTAINER (file_menu), activate_menu); + gtk_tooltips_set_tip (tooltips, activate_menu, _("Activate the XScreenSaver daemon now (locking the screen if so configured.)"), NULL); + + lock_menu = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (lock_menu)->child), + _("_Lock Screen Now")); + gtk_widget_add_accelerator (lock_menu, "activate_item", file_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (lock_menu, "lock_menu"); + gtk_widget_ref (lock_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_menu", lock_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lock_menu); + gtk_container_add (GTK_CONTAINER (file_menu), lock_menu); + gtk_tooltips_set_tip (tooltips, lock_menu, _("Lock the screen now (even if \"Lock Screen\" is unchecked.)"), NULL); + + kill_menu = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (kill_menu)->child), + _("_Kill Daemon")); + gtk_widget_add_accelerator (kill_menu, "activate_item", file_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (kill_menu, "kill_menu"); + gtk_widget_ref (kill_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "kill_menu", kill_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (kill_menu); + gtk_container_add (GTK_CONTAINER (file_menu), kill_menu); + gtk_tooltips_set_tip (tooltips, kill_menu, _("Tell the running XScreenSaver daemon to exit."), NULL); + + restart = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (restart)->child), + _("_Restart Daemon")); + gtk_widget_add_accelerator (restart, "activate_item", file_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (restart, "restart"); + gtk_widget_ref (restart); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "restart", restart, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (restart); + gtk_container_add (GTK_CONTAINER (file_menu), restart); + gtk_tooltips_set_tip (tooltips, restart, _("Kill and re-launch the XScreenSaver daemon."), NULL); + + separator1 = gtk_menu_item_new (); + gtk_widget_set_name (separator1, "separator1"); + gtk_widget_ref (separator1); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "separator1", separator1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (separator1); + gtk_container_add (GTK_CONTAINER (file_menu), separator1); + gtk_widget_set_sensitive (separator1, FALSE); + + exit_menu = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (exit_menu)->child), + _("_Exit")); + gtk_widget_add_accelerator (exit_menu, "activate_item", file_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (exit_menu, "exit_menu"); + gtk_widget_ref (exit_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "exit_menu", exit_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (exit_menu); + gtk_container_add (GTK_CONTAINER (file_menu), exit_menu); + gtk_tooltips_set_tip (tooltips, exit_menu, _("Exit the xscreensaver-demo program (but leave the XScreenSaver daemon running in the background.)"), NULL); + + help = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (help)->child), + _("_Help")); + gtk_widget_add_accelerator (help, "activate_item", accel_group, + tmp_key, GDK_MOD1_MASK, (GtkAccelFlags) 0); + gtk_widget_set_name (help, "help"); + gtk_widget_ref (help); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "help", help, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (help); + gtk_container_add (GTK_CONTAINER (menubar), help); + + help_menu = gtk_menu_new (); + gtk_widget_set_name (help_menu, "help_menu"); + gtk_widget_ref (help_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "help_menu", help_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu); + help_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (help_menu)); + + about_menu = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (about_menu)->child), + _("_About...")); + gtk_widget_add_accelerator (about_menu, "activate_item", help_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (about_menu, "about_menu"); + gtk_widget_ref (about_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "about_menu", about_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (about_menu); + gtk_container_add (GTK_CONTAINER (help_menu), about_menu); + gtk_tooltips_set_tip (tooltips, about_menu, _("Display version information."), NULL); + + doc_menu = gtk_menu_item_new_with_label (""); + tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (doc_menu)->child), + _("_Documentation...")); + gtk_widget_add_accelerator (doc_menu, "activate_item", help_menu_accels, + tmp_key, 0, 0); + gtk_widget_set_name (doc_menu, "doc_menu"); + gtk_widget_ref (doc_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "doc_menu", doc_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (doc_menu); + gtk_container_add (GTK_CONTAINER (help_menu), doc_menu); + gtk_tooltips_set_tip (tooltips, doc_menu, _("Go to the documentation on the XScreenSaver web page."), NULL); + + notebook = gtk_notebook_new (); + gtk_widget_set_name (notebook, "notebook"); + gtk_widget_ref (notebook); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "notebook", notebook, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (notebook); + gtk_box_pack_start (GTK_BOX (outer_vbox), notebook, TRUE, TRUE, 0); + + demos_table = gtk_table_new (2, 2, FALSE); + gtk_widget_set_name (demos_table, "demos_table"); + gtk_widget_ref (demos_table); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demos_table", demos_table, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (demos_table); + gtk_container_add (GTK_CONTAINER (notebook), demos_table); + gtk_container_set_border_width (GTK_CONTAINER (demos_table), 10); + + blanking_table = gtk_table_new (3, 4, FALSE); + gtk_widget_set_name (blanking_table, "blanking_table"); + gtk_widget_ref (blanking_table); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "blanking_table", blanking_table, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (blanking_table); + gtk_table_attach (GTK_TABLE (demos_table), blanking_table, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_table_set_row_spacings (GTK_TABLE (blanking_table), 2); + + cycle_label = gtk_label_new (_("Cycle After")); + gtk_widget_set_name (cycle_label, "cycle_label"); + gtk_widget_ref (cycle_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cycle_label", cycle_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cycle_label); + gtk_table_attach (GTK_TABLE (blanking_table), cycle_label, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (cycle_label), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (cycle_label), 1, 0.5); + gtk_misc_set_padding (GTK_MISC (cycle_label), 8, 0); + + lock_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (lock_button_eventbox, "lock_button_eventbox"); + gtk_widget_ref (lock_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_button_eventbox", lock_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lock_button_eventbox); + gtk_table_attach (GTK_TABLE (blanking_table), lock_button_eventbox, 0, 2, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_tooltips_set_tip (tooltips, lock_button_eventbox, _("Whether a password should be required to un-blank the screen."), NULL); + + lock_button = gtk_check_button_new_with_label (_("Lock Screen After")); + gtk_widget_set_name (lock_button, "lock_button"); + gtk_widget_ref (lock_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_button", lock_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lock_button); + gtk_container_add (GTK_CONTAINER (lock_button_eventbox), lock_button); + + timeout_label = gtk_label_new (_("Blank After")); + gtk_widget_set_name (timeout_label, "timeout_label"); + gtk_widget_ref (timeout_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "timeout_label", timeout_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (timeout_label); + gtk_table_attach (GTK_TABLE (blanking_table), timeout_label, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (timeout_label), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (timeout_label), 1, 0.5); + gtk_misc_set_padding (GTK_MISC (timeout_label), 8, 0); + + timeout_spinbutton_adj = gtk_adjustment_new (0, 1, 720, 1, 30, 30); + timeout_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (timeout_spinbutton_adj), 15, 0); + gtk_widget_set_name (timeout_spinbutton, "timeout_spinbutton"); + gtk_widget_ref (timeout_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "timeout_spinbutton", timeout_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (timeout_spinbutton); + gtk_table_attach (GTK_TABLE (blanking_table), timeout_spinbutton, 2, 3, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_tooltips_set_tip (tooltips, timeout_spinbutton, _("How long before the monitor goes completely black."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (timeout_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (timeout_spinbutton), TRUE); + + timeout_mlabel = gtk_label_new (_("minutes")); + gtk_widget_set_name (timeout_mlabel, "timeout_mlabel"); + gtk_widget_ref (timeout_mlabel); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "timeout_mlabel", timeout_mlabel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (timeout_mlabel); + gtk_table_attach (GTK_TABLE (blanking_table), timeout_mlabel, 3, 4, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (timeout_mlabel), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (timeout_mlabel), 0, 0.5); + + cycle_mlabel = gtk_label_new (_("minutes")); + gtk_widget_set_name (cycle_mlabel, "cycle_mlabel"); + gtk_widget_ref (cycle_mlabel); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cycle_mlabel", cycle_mlabel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cycle_mlabel); + gtk_table_attach (GTK_TABLE (blanking_table), cycle_mlabel, 3, 4, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (cycle_mlabel), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (cycle_mlabel), 0, 0.5); + + lock_mlabel = gtk_label_new (_("minutes")); + gtk_widget_set_name (lock_mlabel, "lock_mlabel"); + gtk_widget_ref (lock_mlabel); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_mlabel", lock_mlabel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lock_mlabel); + gtk_table_attach (GTK_TABLE (blanking_table), lock_mlabel, 3, 4, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (lock_mlabel), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (lock_mlabel), 0, 0.5); + + lock_spinbutton_adj = gtk_adjustment_new (0, 0, 720, 1, 30, 30); + lock_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (lock_spinbutton_adj), 15, 0); + gtk_widget_set_name (lock_spinbutton, "lock_spinbutton"); + gtk_widget_ref (lock_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "lock_spinbutton", lock_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (lock_spinbutton); + gtk_table_attach (GTK_TABLE (blanking_table), lock_spinbutton, 2, 3, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 10); + gtk_tooltips_set_tip (tooltips, lock_spinbutton, _("How long before the monitor goes completely black."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (lock_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (lock_spinbutton), TRUE); + + cycle_spinbutton_adj = gtk_adjustment_new (0, 1, 720, 1, 30, 30); + cycle_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (cycle_spinbutton_adj), 15, 0); + gtk_widget_set_name (cycle_spinbutton, "cycle_spinbutton"); + gtk_widget_ref (cycle_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cycle_spinbutton", cycle_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cycle_spinbutton); + gtk_table_attach (GTK_TABLE (blanking_table), cycle_spinbutton, 2, 3, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_tooltips_set_tip (tooltips, cycle_spinbutton, _("How long before the monitor goes completely black."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (cycle_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (cycle_spinbutton), TRUE); + + demo_manual_hbbox = gtk_hbutton_box_new (); + gtk_widget_set_name (demo_manual_hbbox, "demo_manual_hbbox"); + gtk_widget_ref (demo_manual_hbbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo_manual_hbbox", demo_manual_hbbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (demo_manual_hbbox); + gtk_table_attach (GTK_TABLE (demos_table), demo_manual_hbbox, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_button_box_set_layout (GTK_BUTTON_BOX (demo_manual_hbbox), GTK_BUTTONBOX_SPREAD); + + demo = gtk_button_new_with_label (_("Preview")); + gtk_widget_set_name (demo, "demo"); + gtk_widget_ref (demo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo", demo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (demo); + gtk_container_add (GTK_CONTAINER (demo_manual_hbbox), demo); + STFU GTK_WIDGET_SET_FLAGS (demo, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, demo, _("Demo the selected screen saver in full-screen mode (click the mouse to return.)"), NULL); + + settings = gtk_button_new_with_label (_("Settings...")); + gtk_widget_set_name (settings, "settings"); + gtk_widget_ref (settings); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "settings", settings, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (settings); + gtk_container_add (GTK_CONTAINER (demo_manual_hbbox), settings); + STFU GTK_WIDGET_SET_FLAGS (settings, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, settings, _("Customization and explanation of the selected screen saver."), NULL); + + list_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (list_vbox, "list_vbox"); + gtk_widget_ref (list_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "list_vbox", list_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (list_vbox); + gtk_table_attach (GTK_TABLE (demos_table), list_vbox, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_container_set_border_width (GTK_CONTAINER (list_vbox), 10); + + mode_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (mode_hbox, "mode_hbox"); + gtk_widget_ref (mode_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "mode_hbox", mode_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (mode_hbox); + gtk_box_pack_start (GTK_BOX (list_vbox), mode_hbox, FALSE, TRUE, 10); + + mode_label = gtk_label_new (_("Mode:")); + gtk_widget_set_name (mode_label, "mode_label"); + gtk_widget_ref (mode_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "mode_label", mode_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (mode_label); + gtk_box_pack_start (GTK_BOX (mode_hbox), mode_label, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (mode_label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (mode_label), 0, 0.5); + + mode_menu = gtk_option_menu_new (); + gtk_widget_set_name (mode_menu, "mode_menu"); + gtk_widget_ref (mode_menu); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "mode_menu", mode_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (mode_menu); + gtk_box_pack_start (GTK_BOX (mode_hbox), mode_menu, FALSE, FALSE, 4); + mode_menu_menu = gtk_menu_new (); + glade_menuitem = gtk_menu_item_new_with_label (_("Disable Screen Saver")); + gtk_widget_show (glade_menuitem); + gtk_menu_append (GTK_MENU (mode_menu_menu), glade_menuitem); + glade_menuitem = gtk_menu_item_new_with_label (_("Blank Screen Only")); + gtk_widget_show (glade_menuitem); + gtk_menu_append (GTK_MENU (mode_menu_menu), glade_menuitem); + glade_menuitem = gtk_menu_item_new_with_label (_("Only One Screen Saver")); + gtk_widget_show (glade_menuitem); + gtk_menu_append (GTK_MENU (mode_menu_menu), glade_menuitem); + glade_menuitem = gtk_menu_item_new_with_label (_("Random Screen Saver")); + gtk_widget_show (glade_menuitem); + gtk_menu_append (GTK_MENU (mode_menu_menu), glade_menuitem); + gtk_option_menu_set_menu (GTK_OPTION_MENU (mode_menu), mode_menu_menu); + gtk_option_menu_set_history (GTK_OPTION_MENU (mode_menu), 3); + + col_head_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (col_head_hbox, "col_head_hbox"); + gtk_widget_ref (col_head_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "col_head_hbox", col_head_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (col_head_hbox); + gtk_box_pack_start (GTK_BOX (list_vbox), col_head_hbox, FALSE, TRUE, 0); + + use_col_frame = gtk_frame_new (NULL); + gtk_widget_set_name (use_col_frame, "use_col_frame"); + gtk_widget_ref (use_col_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "use_col_frame", use_col_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (use_col_frame); + gtk_box_pack_start (GTK_BOX (col_head_hbox), use_col_frame, FALSE, FALSE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (use_col_frame), GTK_SHADOW_OUT); + + use_label = gtk_label_new (_("Use")); + gtk_widget_set_name (use_label, "use_label"); + gtk_widget_ref (use_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "use_label", use_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (use_label); + gtk_container_add (GTK_CONTAINER (use_col_frame), use_label); + gtk_label_set_justify (GTK_LABEL (use_label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (use_label), 0, 0.5); + gtk_misc_set_padding (GTK_MISC (use_label), 3, 0); + + saver_col_frame = gtk_frame_new (NULL); + gtk_widget_set_name (saver_col_frame, "saver_col_frame"); + gtk_widget_ref (saver_col_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "saver_col_frame", saver_col_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (saver_col_frame); + gtk_box_pack_start (GTK_BOX (col_head_hbox), saver_col_frame, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (saver_col_frame), GTK_SHADOW_OUT); + + saver_label = gtk_label_new (_("Screen Saver")); + gtk_widget_set_name (saver_label, "saver_label"); + gtk_widget_ref (saver_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "saver_label", saver_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (saver_label); + gtk_container_add (GTK_CONTAINER (saver_col_frame), saver_label); + gtk_label_set_justify (GTK_LABEL (saver_label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (saver_label), 0, 0.5); + gtk_misc_set_padding (GTK_MISC (saver_label), 6, 0); + + scroller = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_name (scroller, "scroller"); + gtk_widget_ref (scroller); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "scroller", scroller, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (scroller); + gtk_box_pack_start (GTK_BOX (list_vbox), scroller, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + + viewport = gtk_viewport_new (NULL, NULL); + gtk_widget_set_name (viewport, "viewport"); + gtk_widget_ref (viewport); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "viewport", viewport, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (viewport); + gtk_container_add (GTK_CONTAINER (scroller), viewport); + gtk_container_set_border_width (GTK_CONTAINER (viewport), 1); + + list = gtk_list_new (); + gtk_widget_set_name (list, "list"); + gtk_widget_ref (list); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "list", list, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (list); + gtk_container_add (GTK_CONTAINER (viewport), list); + + centering_hbox = gtk_hbox_new (TRUE, 0); + gtk_widget_set_name (centering_hbox, "centering_hbox"); + gtk_widget_ref (centering_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "centering_hbox", centering_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (centering_hbox); + gtk_box_pack_end (GTK_BOX (list_vbox), centering_hbox, FALSE, TRUE, 0); + + next_prev_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (next_prev_hbox, "next_prev_hbox"); + gtk_widget_ref (next_prev_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "next_prev_hbox", next_prev_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (next_prev_hbox); + gtk_box_pack_start (GTK_BOX (centering_hbox), next_prev_hbox, FALSE, FALSE, 0); + + next = gtk_button_new_with_label (_("\\/")); + gtk_widget_set_name (next, "next"); + gtk_widget_ref (next); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "next", next, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (next); + gtk_box_pack_start (GTK_BOX (next_prev_hbox), next, FALSE, FALSE, 0); + STFU GTK_WIDGET_SET_FLAGS (next, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, next, _("Run the next screen saver in the list in full-screen mode (click the mouse to return.)"), NULL); + + prev = gtk_button_new_with_label (_("/\\")); + gtk_widget_set_name (prev, "prev"); + gtk_widget_ref (prev); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "prev", prev, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (prev); + gtk_box_pack_start (GTK_BOX (next_prev_hbox), prev, FALSE, FALSE, 0); + STFU GTK_WIDGET_SET_FLAGS (prev, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, prev, _("Run the previous screen saver in the list in full-screen mode (click the mouse to return.)"), NULL); + + preview_frame = gtk_frame_new (_("Description")); + gtk_widget_set_name (preview_frame, "preview_frame"); + gtk_widget_ref (preview_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "preview_frame", preview_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (preview_frame); + gtk_table_attach (GTK_TABLE (demos_table), preview_frame, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 6); + + preview_aspectframe = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.33, FALSE); + gtk_widget_set_name (preview_aspectframe, "preview_aspectframe"); + gtk_widget_ref (preview_aspectframe); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "preview_aspectframe", preview_aspectframe, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (preview_aspectframe); + gtk_container_add (GTK_CONTAINER (preview_frame), preview_aspectframe); + gtk_container_set_border_width (GTK_CONTAINER (preview_aspectframe), 8); + + preview = gtk_drawing_area_new (); + gtk_widget_set_name (preview, "preview"); + gtk_widget_ref (preview); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "preview", preview, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (preview); + gtk_container_add (GTK_CONTAINER (preview_aspectframe), preview); + + demo_tab = gtk_label_new (_("Display Modes")); + gtk_widget_set_name (demo_tab, "demo_tab"); + gtk_widget_ref (demo_tab); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "demo_tab", demo_tab, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (demo_tab); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0), demo_tab); + + options_table = gtk_table_new (2, 2, TRUE); + gtk_widget_set_name (options_table, "options_table"); + gtk_widget_ref (options_table); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "options_table", options_table, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (options_table); + gtk_container_add (GTK_CONTAINER (notebook), options_table); + + diag_frame = gtk_frame_new (_("Diagnostics")); + gtk_widget_set_name (diag_frame, "diag_frame"); + gtk_widget_ref (diag_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "diag_frame", diag_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (diag_frame); + gtk_table_attach (GTK_TABLE (options_table), diag_frame, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_container_set_border_width (GTK_CONTAINER (diag_frame), 10); + + diag_hbox = gtk_hbox_new (FALSE, 8); + gtk_widget_set_name (diag_hbox, "diag_hbox"); + gtk_widget_ref (diag_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "diag_hbox", diag_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (diag_hbox); + gtk_container_add (GTK_CONTAINER (diag_frame), diag_hbox); + gtk_container_set_border_width (GTK_CONTAINER (diag_hbox), 8); + + diag_logo = create_pixmap (xscreensaver_demo, "screensaver-diagnostic.png"); + gtk_widget_set_name (diag_logo, "diag_logo"); + gtk_widget_ref (diag_logo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "diag_logo", diag_logo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (diag_logo); + gtk_box_pack_start (GTK_BOX (diag_hbox), diag_logo, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (diag_logo), 0.5, 0); + + diag_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (diag_vbox, "diag_vbox"); + gtk_widget_ref (diag_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "diag_vbox", diag_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (diag_vbox); + gtk_box_pack_start (GTK_BOX (diag_hbox), diag_vbox, TRUE, TRUE, 0); + + verbose_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (verbose_button_eventbox, "verbose_button_eventbox"); + gtk_widget_ref (verbose_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "verbose_button_eventbox", verbose_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (verbose_button_eventbox); + gtk_box_pack_start (GTK_BOX (diag_vbox), verbose_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, verbose_button_eventbox, _("Whether the daemon should print lots of debugging information."), NULL); + + verbose_button = gtk_check_button_new_with_label (_("Verbose Diagnostics")); + gtk_widget_set_name (verbose_button, "verbose_button"); + gtk_widget_ref (verbose_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "verbose_button", verbose_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (verbose_button); + gtk_container_add (GTK_CONTAINER (verbose_button_eventbox), verbose_button); + + capture_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (capture_button_eventbox, "capture_button_eventbox"); + gtk_widget_ref (capture_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "capture_button_eventbox", capture_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (capture_button_eventbox); + gtk_box_pack_start (GTK_BOX (diag_vbox), capture_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, capture_button_eventbox, _("Whether any error output of the display modes should be redirected to the screen."), NULL); + + capture_button = gtk_check_button_new_with_label (_("Display Subprocess Errors")); + gtk_widget_set_name (capture_button, "capture_button"); + gtk_widget_ref (capture_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "capture_button", capture_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (capture_button); + gtk_container_add (GTK_CONTAINER (capture_button_eventbox), capture_button); + + splash_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (splash_button_eventbox, "splash_button_eventbox"); + gtk_widget_ref (splash_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "splash_button_eventbox", splash_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (splash_button_eventbox); + gtk_box_pack_start (GTK_BOX (diag_vbox), splash_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, splash_button_eventbox, _("Whether the splash screen (with the version number and `Help' button) should be momentarily displayed when the daemon first starts up."), NULL); + + splash_button = gtk_check_button_new_with_label (_("Display Splash Screen at Startup")); + gtk_widget_set_name (splash_button, "splash_button"); + gtk_widget_ref (splash_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "splash_button", splash_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (splash_button); + gtk_container_add (GTK_CONTAINER (splash_button_eventbox), splash_button); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (splash_button), TRUE); + + cmap_frame = gtk_frame_new (_("Colormaps")); + gtk_widget_set_name (cmap_frame, "cmap_frame"); + gtk_widget_ref (cmap_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmap_frame", cmap_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmap_frame); + gtk_table_attach (GTK_TABLE (options_table), cmap_frame, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_container_set_border_width (GTK_CONTAINER (cmap_frame), 10); + + cmap_hbox = gtk_hbox_new (FALSE, 8); + gtk_widget_set_name (cmap_hbox, "cmap_hbox"); + gtk_widget_ref (cmap_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmap_hbox", cmap_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmap_hbox); + gtk_container_add (GTK_CONTAINER (cmap_frame), cmap_hbox); + gtk_container_set_border_width (GTK_CONTAINER (cmap_hbox), 8); + + cmap_logo = create_pixmap (xscreensaver_demo, "screensaver-colorselector.png"); + gtk_widget_set_name (cmap_logo, "cmap_logo"); + gtk_widget_ref (cmap_logo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmap_logo", cmap_logo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmap_logo); + gtk_box_pack_start (GTK_BOX (cmap_hbox), cmap_logo, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (cmap_logo), 0.5, 0); + + cmap_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (cmap_vbox, "cmap_vbox"); + gtk_widget_ref (cmap_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmap_vbox", cmap_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmap_vbox); + gtk_box_pack_start (GTK_BOX (cmap_hbox), cmap_vbox, TRUE, TRUE, 0); + + install_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (install_button_eventbox, "install_button_eventbox"); + gtk_widget_ref (install_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "install_button_eventbox", install_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (install_button_eventbox); + gtk_box_pack_start (GTK_BOX (cmap_vbox), install_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, install_button_eventbox, _("Whether to install a private colormap when running in 8-bit mode on the default Visual."), NULL); + + install_button = gtk_check_button_new_with_label (_("Install Colormap")); + gtk_widget_set_name (install_button, "install_button"); + gtk_widget_ref (install_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "install_button", install_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (install_button); + gtk_container_add (GTK_CONTAINER (install_button_eventbox), install_button); + + cmap_hr = gtk_hseparator_new (); + gtk_widget_set_name (cmap_hr, "cmap_hr"); + gtk_widget_ref (cmap_hr); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "cmap_hr", cmap_hr, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmap_hr); + gtk_box_pack_start (GTK_BOX (cmap_vbox), cmap_hr, FALSE, FALSE, 4); + + fade_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (fade_button_eventbox, "fade_button_eventbox"); + gtk_widget_ref (fade_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_button_eventbox", fade_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_button_eventbox); + gtk_box_pack_start (GTK_BOX (cmap_vbox), fade_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, fade_button_eventbox, _("Whether the screen should slowly fade to black when the screen saver activates."), NULL); + + fade_button = gtk_check_button_new_with_label (_("Fade To Black When Blanking")); + gtk_widget_set_name (fade_button, "fade_button"); + gtk_widget_ref (fade_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_button", fade_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_button); + gtk_container_add (GTK_CONTAINER (fade_button_eventbox), fade_button); + + unfade_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (unfade_button_eventbox, "unfade_button_eventbox"); + gtk_widget_ref (unfade_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "unfade_button_eventbox", unfade_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (unfade_button_eventbox); + gtk_box_pack_start (GTK_BOX (cmap_vbox), unfade_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, unfade_button_eventbox, _("Whether the screen should slowly fade in from black when the screen saver deactivates."), NULL); + + unfade_button = gtk_check_button_new_with_label (_("Fade From Black When Unblanking")); + gtk_widget_set_name (unfade_button, "unfade_button"); + gtk_widget_ref (unfade_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "unfade_button", unfade_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (unfade_button); + gtk_container_add (GTK_CONTAINER (unfade_button_eventbox), unfade_button); + + fade_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (fade_hbox, "fade_hbox"); + gtk_widget_ref (fade_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_hbox", fade_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_hbox); + gtk_box_pack_start (GTK_BOX (cmap_vbox), fade_hbox, FALSE, FALSE, 0); + + fade_dummy = gtk_label_new (""); + gtk_widget_set_name (fade_dummy, "fade_dummy"); + gtk_widget_ref (fade_dummy); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_dummy", fade_dummy, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_dummy); + gtk_box_pack_start (GTK_BOX (fade_hbox), fade_dummy, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (fade_dummy), GTK_JUSTIFY_LEFT); + gtk_misc_set_padding (GTK_MISC (fade_dummy), 3, 0); + + fade_label = gtk_label_new (_("Fade Duration")); + gtk_widget_set_name (fade_label, "fade_label"); + gtk_widget_ref (fade_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_label", fade_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_label); + gtk_box_pack_start (GTK_BOX (fade_hbox), fade_label, FALSE, FALSE, 10); + gtk_label_set_justify (GTK_LABEL (fade_label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (fade_label), 0, 0.5); + + fade_spinbutton_adj = gtk_adjustment_new (0, 0, 10, 1, 1, 1); + fade_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (fade_spinbutton_adj), 1, 0); + gtk_widget_set_name (fade_spinbutton, "fade_spinbutton"); + gtk_widget_ref (fade_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_spinbutton", fade_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_spinbutton); + gtk_box_pack_start (GTK_BOX (fade_hbox), fade_spinbutton, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, fade_spinbutton, _("How long it should take for the screen to fade in and out."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (fade_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (fade_spinbutton), TRUE); + + fade_sec_label = gtk_label_new (_("seconds")); + gtk_widget_set_name (fade_sec_label, "fade_sec_label"); + gtk_widget_ref (fade_sec_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "fade_sec_label", fade_sec_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (fade_sec_label); + gtk_box_pack_start (GTK_BOX (fade_hbox), fade_sec_label, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (fade_sec_label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (fade_sec_label), 0, 0.5); + + dpms_frame = gtk_frame_new (_("Display Power Management")); + gtk_widget_set_name (dpms_frame, "dpms_frame"); + gtk_widget_ref (dpms_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_frame", dpms_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_frame); + gtk_table_attach (GTK_TABLE (options_table), dpms_frame, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_container_set_border_width (GTK_CONTAINER (dpms_frame), 10); + + dpms_hbox = gtk_hbox_new (FALSE, 8); + gtk_widget_set_name (dpms_hbox, "dpms_hbox"); + gtk_widget_ref (dpms_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_hbox", dpms_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_hbox); + gtk_container_add (GTK_CONTAINER (dpms_frame), dpms_hbox); + gtk_container_set_border_width (GTK_CONTAINER (dpms_hbox), 8); + + dpms_logo = create_pixmap (xscreensaver_demo, "screensaver-power.png"); + gtk_widget_set_name (dpms_logo, "dpms_logo"); + gtk_widget_ref (dpms_logo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_logo", dpms_logo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_logo); + gtk_box_pack_start (GTK_BOX (dpms_hbox), dpms_logo, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (dpms_logo), 0.5, 0); + + dpms_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (dpms_vbox, "dpms_vbox"); + gtk_widget_ref (dpms_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_vbox", dpms_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_vbox); + gtk_box_pack_start (GTK_BOX (dpms_hbox), dpms_vbox, FALSE, FALSE, 0); + + dpms_button_eventbox = gtk_event_box_new (); + gtk_widget_set_name (dpms_button_eventbox, "dpms_button_eventbox"); + gtk_widget_ref (dpms_button_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_button_eventbox", dpms_button_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_button_eventbox); + gtk_box_pack_start (GTK_BOX (dpms_vbox), dpms_button_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, dpms_button_eventbox, _("Whether the monitor should be powered down after a while."), NULL); + + dpms_button = gtk_check_button_new_with_label (_("Power Management Enabled")); + gtk_widget_set_name (dpms_button, "dpms_button"); + gtk_widget_ref (dpms_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_button", dpms_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_button); + gtk_container_add (GTK_CONTAINER (dpms_button_eventbox), dpms_button); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dpms_button), TRUE); + + dpms_table = gtk_table_new (3, 3, FALSE); + gtk_widget_set_name (dpms_table, "dpms_table"); + gtk_widget_ref (dpms_table); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_table", dpms_table, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_table); + gtk_box_pack_start (GTK_BOX (dpms_vbox), dpms_table, FALSE, FALSE, 0); + gtk_table_set_row_spacings (GTK_TABLE (dpms_table), 2); + + dpms_standby_spinbutton_adj = gtk_adjustment_new (0, 0, 1440, 1, 30, 30); + dpms_standby_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (dpms_standby_spinbutton_adj), 15, 0); + gtk_widget_set_name (dpms_standby_spinbutton, "dpms_standby_spinbutton"); + gtk_widget_ref (dpms_standby_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_standby_spinbutton", dpms_standby_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_standby_spinbutton); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_standby_spinbutton, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_tooltips_set_tip (tooltips, dpms_standby_spinbutton, _("How long before the monitor goes completely black."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dpms_standby_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (dpms_standby_spinbutton), TRUE); + + dpms_standby_mlabel = gtk_label_new (_("minutes")); + gtk_widget_set_name (dpms_standby_mlabel, "dpms_standby_mlabel"); + gtk_widget_ref (dpms_standby_mlabel); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_standby_mlabel", dpms_standby_mlabel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_standby_mlabel); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_standby_mlabel, 2, 3, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (dpms_standby_mlabel), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (dpms_standby_mlabel), 0, 0.5); + + dpms_suspend_mlabel = gtk_label_new (_("minutes")); + gtk_widget_set_name (dpms_suspend_mlabel, "dpms_suspend_mlabel"); + gtk_widget_ref (dpms_suspend_mlabel); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_suspend_mlabel", dpms_suspend_mlabel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_suspend_mlabel); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_suspend_mlabel, 2, 3, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (dpms_suspend_mlabel), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (dpms_suspend_mlabel), 0, 0.5); + + dpms_off_mlabel = gtk_label_new (_("minutes")); + gtk_widget_set_name (dpms_off_mlabel, "dpms_off_mlabel"); + gtk_widget_ref (dpms_off_mlabel); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_off_mlabel", dpms_off_mlabel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_off_mlabel); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_off_mlabel, 2, 3, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (dpms_off_mlabel), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (dpms_off_mlabel), 0, 0.5); + + dpms_off_label = gtk_label_new (_("Off After")); + gtk_widget_set_name (dpms_off_label, "dpms_off_label"); + gtk_widget_ref (dpms_off_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_off_label", dpms_off_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_off_label); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_off_label, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (dpms_off_label), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (dpms_off_label), 1, 0.5); + gtk_misc_set_padding (GTK_MISC (dpms_off_label), 10, 0); + + dpms_suspend_label = gtk_label_new (_("Suspend After")); + gtk_widget_set_name (dpms_suspend_label, "dpms_suspend_label"); + gtk_widget_ref (dpms_suspend_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_suspend_label", dpms_suspend_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_suspend_label); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_suspend_label, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (dpms_suspend_label), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (dpms_suspend_label), 1, 0.5); + gtk_misc_set_padding (GTK_MISC (dpms_suspend_label), 10, 0); + + dpms_standby_label = gtk_label_new (_("Standby After")); + gtk_widget_set_name (dpms_standby_label, "dpms_standby_label"); + gtk_widget_ref (dpms_standby_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_standby_label", dpms_standby_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_standby_label); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_standby_label, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (dpms_standby_label), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (dpms_standby_label), 1, 0.5); + gtk_misc_set_padding (GTK_MISC (dpms_standby_label), 10, 0); + + dpms_suspend_spinbutton_adj = gtk_adjustment_new (0, 0, 1440, 1, 30, 30); + dpms_suspend_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (dpms_suspend_spinbutton_adj), 15, 0); + gtk_widget_set_name (dpms_suspend_spinbutton, "dpms_suspend_spinbutton"); + gtk_widget_ref (dpms_suspend_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_suspend_spinbutton", dpms_suspend_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_suspend_spinbutton); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_suspend_spinbutton, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_tooltips_set_tip (tooltips, dpms_suspend_spinbutton, _("How long until the monitor goes into power-saving mode."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dpms_suspend_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (dpms_suspend_spinbutton), TRUE); + + dpms_off_spinbutton_adj = gtk_adjustment_new (0, 0, 1440, 1, 30, 30); + dpms_off_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (dpms_off_spinbutton_adj), 15, 0); + gtk_widget_set_name (dpms_off_spinbutton, "dpms_off_spinbutton"); + gtk_widget_ref (dpms_off_spinbutton); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "dpms_off_spinbutton", dpms_off_spinbutton, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dpms_off_spinbutton); + gtk_table_attach (GTK_TABLE (dpms_table), dpms_off_spinbutton, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_tooltips_set_tip (tooltips, dpms_off_spinbutton, _("How long until the monitor powers down."), NULL); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dpms_off_spinbutton), TRUE); + gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (dpms_off_spinbutton), TRUE); + + grab_frame = gtk_frame_new (_("Image Manipulation")); + gtk_widget_set_name (grab_frame, "grab_frame"); + gtk_widget_ref (grab_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_frame", grab_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_frame); + gtk_table_attach (GTK_TABLE (options_table), grab_frame, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_container_set_border_width (GTK_CONTAINER (grab_frame), 10); + + grab_hbox = gtk_hbox_new (FALSE, 8); + gtk_widget_set_name (grab_hbox, "grab_hbox"); + gtk_widget_ref (grab_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_hbox", grab_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_hbox); + gtk_container_add (GTK_CONTAINER (grab_frame), grab_hbox); + gtk_container_set_border_width (GTK_CONTAINER (grab_hbox), 8); + + img_logo = create_pixmap (xscreensaver_demo, "screensaver-snap.png"); + gtk_widget_set_name (img_logo, "img_logo"); + gtk_widget_ref (img_logo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "img_logo", img_logo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (img_logo); + gtk_box_pack_start (GTK_BOX (grab_hbox), img_logo, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (img_logo), 0.5, 0); + + grab_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (grab_vbox, "grab_vbox"); + gtk_widget_ref (grab_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_vbox", grab_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_vbox); + gtk_box_pack_start (GTK_BOX (grab_hbox), grab_vbox, TRUE, TRUE, 0); + + grab_desk_eventbox = gtk_event_box_new (); + gtk_widget_set_name (grab_desk_eventbox, "grab_desk_eventbox"); + gtk_widget_ref (grab_desk_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_desk_eventbox", grab_desk_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_desk_eventbox); + gtk_box_pack_start (GTK_BOX (grab_vbox), grab_desk_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, grab_desk_eventbox, _("Whether the image-manipulating modes should be allowed to operate on an image of your desktop."), NULL); + + grab_desk_button = gtk_check_button_new_with_label (_("Grab Desktop Images")); + gtk_widget_set_name (grab_desk_button, "grab_desk_button"); + gtk_widget_ref (grab_desk_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_desk_button", grab_desk_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_desk_button); + gtk_container_add (GTK_CONTAINER (grab_desk_eventbox), grab_desk_button); + + grab_video_eventbox = gtk_event_box_new (); + gtk_widget_set_name (grab_video_eventbox, "grab_video_eventbox"); + gtk_widget_ref (grab_video_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_video_eventbox", grab_video_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_video_eventbox); + gtk_box_pack_start (GTK_BOX (grab_vbox), grab_video_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, grab_video_eventbox, _("Whether the image-manipulating modes should operate on images captured from the system's video input (if there is one)."), NULL); + + grab_video_button = gtk_check_button_new_with_label (_("Grab Video Frames")); + gtk_widget_set_name (grab_video_button, "grab_video_button"); + gtk_widget_ref (grab_video_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_video_button", grab_video_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_video_button); + gtk_container_add (GTK_CONTAINER (grab_video_eventbox), grab_video_button); + + grab_image_eventbox = gtk_event_box_new (); + gtk_widget_set_name (grab_image_eventbox, "grab_image_eventbox"); + gtk_widget_ref (grab_image_eventbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_image_eventbox", grab_image_eventbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_image_eventbox); + gtk_box_pack_start (GTK_BOX (grab_vbox), grab_image_eventbox, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, grab_image_eventbox, _("Whether the image-manipulating modes should load image files."), NULL); + + grab_image_button = gtk_check_button_new_with_label (_("Choose Random Image:")); + gtk_widget_set_name (grab_image_button, "grab_image_button"); + gtk_widget_ref (grab_image_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_image_button", grab_image_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_image_button); + gtk_container_add (GTK_CONTAINER (grab_image_eventbox), grab_image_button); + + image_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (image_hbox, "image_hbox"); + gtk_widget_ref (image_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "image_hbox", image_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (image_hbox); + gtk_box_pack_start (GTK_BOX (grab_vbox), image_hbox, FALSE, FALSE, 0); + + grab_dummy = gtk_label_new (""); + gtk_widget_set_name (grab_dummy, "grab_dummy"); + gtk_widget_ref (grab_dummy); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "grab_dummy", grab_dummy, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (grab_dummy); + gtk_box_pack_start (GTK_BOX (image_hbox), grab_dummy, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (grab_dummy), GTK_JUSTIFY_LEFT); + gtk_misc_set_padding (GTK_MISC (grab_dummy), 8, 0); + + image_text = gtk_entry_new (); + gtk_widget_set_name (image_text, "image_text"); + gtk_widget_ref (image_text); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "image_text", image_text, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (image_text); + gtk_box_pack_start (GTK_BOX (image_hbox), image_text, TRUE, TRUE, 0); + gtk_tooltips_set_tip (tooltips, image_text, _("The local directory, RSS feed or Atom feed from which images will be randomly chosen."), NULL); + + image_browse_button = gtk_button_new_with_label (_("Browse")); + gtk_widget_set_name (image_browse_button, "image_browse_button"); + gtk_widget_ref (image_browse_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "image_browse_button", image_browse_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (image_browse_button); + gtk_box_pack_start (GTK_BOX (image_hbox), image_browse_button, FALSE, FALSE, 4); + + options_tab = gtk_label_new (_("Advanced")); + gtk_widget_set_name (options_tab, "options_tab"); + gtk_widget_ref (options_tab); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_demo), "options_tab", options_tab, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (options_tab); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), options_tab); + + gtk_signal_connect (GTK_OBJECT (activate_menu), "activate", + GTK_SIGNAL_FUNC (activate_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (lock_menu), "activate", + GTK_SIGNAL_FUNC (lock_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (kill_menu), "activate", + GTK_SIGNAL_FUNC (kill_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (restart), "activate", + GTK_SIGNAL_FUNC (restart_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (exit_menu), "activate", + GTK_SIGNAL_FUNC (exit_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (about_menu), "activate", + GTK_SIGNAL_FUNC (about_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (doc_menu), "activate", + GTK_SIGNAL_FUNC (doc_menu_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (notebook), "switch_page", + GTK_SIGNAL_FUNC (switch_page_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (lock_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (timeout_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (timeout_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (timeout_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (lock_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (lock_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (lock_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (cycle_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (cycle_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (cycle_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (demo), "clicked", + GTK_SIGNAL_FUNC (run_this_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (settings), "clicked", + GTK_SIGNAL_FUNC (settings_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (next), "clicked", + GTK_SIGNAL_FUNC (run_next_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (prev), "clicked", + GTK_SIGNAL_FUNC (run_prev_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (verbose_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (capture_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (splash_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (install_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (fade_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (unfade_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (fade_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (fade_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (fade_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_standby_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_standby_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_standby_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_suspend_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_suspend_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_suspend_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_off_spinbutton), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_off_spinbutton), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (dpms_off_spinbutton), "changed", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (grab_desk_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (grab_video_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (grab_image_button), "toggled", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (image_text), "activate", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (image_text), "focus_out_event", + GTK_SIGNAL_FUNC (pref_changed_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (image_browse_button), "clicked", + GTK_SIGNAL_FUNC (browse_image_dir_cb), + NULL); + + gtk_widget_grab_default (next); + gtk_object_set_data (GTK_OBJECT (xscreensaver_demo), "tooltips", tooltips); + + gtk_window_add_accel_group (GTK_WINDOW (xscreensaver_demo), accel_group); + + return xscreensaver_demo; +} + +GtkWidget* +create_xscreensaver_settings_dialog (void) +{ + GtkWidget *xscreensaver_settings_dialog; + GtkWidget *dialog_vbox; + GtkWidget *dialog_top_table; + GtkWidget *opt_frame; + GtkWidget *opt_notebook; + GtkWidget *settings_vbox; + GtkWidget *std_label; + GtkWidget *opt_table; + GtkWidget *cmd_logo; + GtkWidget *visual_hbox; + GtkWidget *visual; + GtkWidget *visual_combo; + GList *visual_combo_items = NULL; + GtkWidget *combo_entry1; + GtkWidget *cmd_label; + GtkWidget *cmd_text; + GtkWidget *adv_label; + GtkWidget *doc_frame; + GtkWidget *doc_vbox; + GtkWidget *doc; + GtkWidget *doc_hbuttonbox; + GtkWidget *manual; + GtkWidget *dialog_action_area; + GtkWidget *actionarea_hbox; + GtkWidget *dialog_hbuttonbox; + GtkWidget *adv_button; + GtkWidget *std_button; + GtkWidget *reset_button; + GtkWidget *ok_cancel_hbuttonbox; + GtkWidget *ok_button; + GtkWidget *cancel_button; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + xscreensaver_settings_dialog = gtk_dialog_new (); + gtk_widget_set_name (xscreensaver_settings_dialog, "xscreensaver_settings_dialog"); + gtk_object_set_data (GTK_OBJECT (xscreensaver_settings_dialog), "xscreensaver_settings_dialog", xscreensaver_settings_dialog); + gtk_window_set_title (GTK_WINDOW (xscreensaver_settings_dialog), _("XScreenSaver: Mode-Specific Settings")); + GTK_WINDOW (xscreensaver_settings_dialog)->type = GTK_WINDOW_DIALOG; + gtk_window_set_modal (GTK_WINDOW (xscreensaver_settings_dialog), TRUE); + gtk_window_set_policy (GTK_WINDOW (xscreensaver_settings_dialog), TRUE, TRUE, FALSE); + gtk_window_set_wmclass (GTK_WINDOW (xscreensaver_settings_dialog), "settings", "XScreenSaver"); + + dialog_vbox = GTK_DIALOG (xscreensaver_settings_dialog)->vbox; + gtk_widget_set_name (dialog_vbox, "dialog_vbox"); + gtk_object_set_data (GTK_OBJECT (xscreensaver_settings_dialog), "dialog_vbox", dialog_vbox); + gtk_widget_show (dialog_vbox); + + dialog_top_table = gtk_table_new (1, 2, FALSE); + gtk_widget_set_name (dialog_top_table, "dialog_top_table"); + gtk_widget_ref (dialog_top_table); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "dialog_top_table", dialog_top_table, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dialog_top_table); + gtk_box_pack_start (GTK_BOX (dialog_vbox), dialog_top_table, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (dialog_top_table), 8); + gtk_table_set_row_spacings (GTK_TABLE (dialog_top_table), 8); + gtk_table_set_col_spacings (GTK_TABLE (dialog_top_table), 8); + + opt_frame = gtk_frame_new (_("Settings")); + gtk_widget_set_name (opt_frame, "opt_frame"); + gtk_widget_ref (opt_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "opt_frame", opt_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (opt_frame); + gtk_table_attach (GTK_TABLE (dialog_top_table), opt_frame, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 4, 8); + + opt_notebook = gtk_notebook_new (); + gtk_widget_set_name (opt_notebook, "opt_notebook"); + gtk_widget_ref (opt_notebook); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "opt_notebook", opt_notebook, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (opt_notebook); + gtk_container_add (GTK_CONTAINER (opt_frame), opt_notebook); + gtk_container_set_border_width (GTK_CONTAINER (opt_notebook), 12); + gtk_notebook_set_show_border (GTK_NOTEBOOK (opt_notebook), FALSE); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (opt_notebook), GTK_POS_BOTTOM); + + settings_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (settings_vbox, "settings_vbox"); + gtk_widget_ref (settings_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "settings_vbox", settings_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (settings_vbox); + gtk_container_add (GTK_CONTAINER (opt_notebook), settings_vbox); + + std_label = gtk_label_new (_("Standard")); + gtk_widget_set_name (std_label, "std_label"); + gtk_widget_ref (std_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "std_label", std_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (std_label); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (opt_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (opt_notebook), 0), std_label); + + opt_table = gtk_table_new (4, 2, FALSE); + gtk_widget_set_name (opt_table, "opt_table"); + gtk_widget_ref (opt_table); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "opt_table", opt_table, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (opt_table); + gtk_container_add (GTK_CONTAINER (opt_notebook), opt_table); + + cmd_logo = create_pixmap (xscreensaver_settings_dialog, "screensaver-cmndln.png"); + gtk_widget_set_name (cmd_logo, "cmd_logo"); + gtk_widget_ref (cmd_logo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "cmd_logo", cmd_logo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmd_logo); + gtk_table_attach (GTK_TABLE (opt_table), cmd_logo, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_misc_set_padding (GTK_MISC (cmd_logo), 4, 8); + + visual_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (visual_hbox, "visual_hbox"); + gtk_widget_ref (visual_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "visual_hbox", visual_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (visual_hbox); + gtk_table_attach (GTK_TABLE (opt_table), visual_hbox, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + visual = gtk_label_new (_("Visual:")); + gtk_widget_set_name (visual, "visual"); + gtk_widget_ref (visual); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "visual", visual, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (visual); + gtk_box_pack_start (GTK_BOX (visual_hbox), visual, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (visual), GTK_JUSTIFY_RIGHT); + gtk_misc_set_alignment (GTK_MISC (visual), 1, 0.5); + gtk_misc_set_padding (GTK_MISC (visual), 4, 0); + + visual_combo = gtk_combo_new (); + gtk_widget_set_name (visual_combo, "visual_combo"); + gtk_widget_ref (visual_combo); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "visual_combo", visual_combo, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (visual_combo); + gtk_box_pack_start (GTK_BOX (visual_hbox), visual_combo, FALSE, FALSE, 0); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Any")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Best")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Default")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Default-N")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("GL")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("TrueColor")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("PseudoColor")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("StaticGray")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("GrayScale")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("DirectColor")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Color")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Gray")); + visual_combo_items = g_list_append (visual_combo_items, (gpointer) _("Mono")); + gtk_combo_set_popdown_strings (GTK_COMBO (visual_combo), visual_combo_items); + g_list_free (visual_combo_items); + + combo_entry1 = GTK_COMBO (visual_combo)->entry; + gtk_widget_set_name (combo_entry1, "combo_entry1"); + gtk_widget_ref (combo_entry1); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "combo_entry1", combo_entry1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry1); + gtk_tooltips_set_tip (tooltips, combo_entry1, _("The X visual type that this demo will require. If that visual is available it will be used, otherwise, this demo will not be run."), NULL); + gtk_entry_set_text (GTK_ENTRY (combo_entry1), _("Any")); + + cmd_label = gtk_label_new (_("Command Line:")); + gtk_widget_set_name (cmd_label, "cmd_label"); + gtk_widget_ref (cmd_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "cmd_label", cmd_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmd_label); + gtk_table_attach (GTK_TABLE (opt_table), cmd_label, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (cmd_label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (cmd_label), 0, 1); + gtk_misc_set_padding (GTK_MISC (cmd_label), 0, 2); + + cmd_text = gtk_entry_new (); + gtk_widget_set_name (cmd_text, "cmd_text"); + gtk_widget_ref (cmd_text); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "cmd_text", cmd_text, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cmd_text); + gtk_table_attach (GTK_TABLE (opt_table), cmd_text, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_widget_set_usize (cmd_text, 80, -2); + + adv_label = gtk_label_new (_("Advanced")); + gtk_widget_set_name (adv_label, "adv_label"); + gtk_widget_ref (adv_label); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "adv_label", adv_label, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (adv_label); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (opt_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (opt_notebook), 1), adv_label); + + doc_frame = gtk_frame_new (_("Description")); + gtk_widget_set_name (doc_frame, "doc_frame"); + gtk_widget_ref (doc_frame); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "doc_frame", doc_frame, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (doc_frame); + gtk_table_attach (GTK_TABLE (dialog_top_table), doc_frame, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 4, 8); + + doc_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (doc_vbox, "doc_vbox"); + gtk_widget_ref (doc_vbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "doc_vbox", doc_vbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (doc_vbox); + gtk_container_add (GTK_CONTAINER (doc_frame), doc_vbox); + + doc = gtk_label_new (""); + gtk_widget_set_name (doc, "doc"); + gtk_widget_ref (doc); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "doc", doc, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (doc); + gtk_box_pack_start (GTK_BOX (doc_vbox), doc, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (doc), GTK_JUSTIFY_LEFT); + gtk_label_set_line_wrap (GTK_LABEL (doc), TRUE); + gtk_misc_set_alignment (GTK_MISC (doc), 0, 0); + gtk_misc_set_padding (GTK_MISC (doc), 10, 10); + + doc_hbuttonbox = gtk_hbutton_box_new (); + gtk_widget_set_name (doc_hbuttonbox, "doc_hbuttonbox"); + gtk_widget_ref (doc_hbuttonbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "doc_hbuttonbox", doc_hbuttonbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (doc_hbuttonbox); + gtk_box_pack_end (GTK_BOX (doc_vbox), doc_hbuttonbox, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (doc_hbuttonbox), 4); + gtk_button_box_set_layout (GTK_BUTTON_BOX (doc_hbuttonbox), GTK_BUTTONBOX_END); + + manual = gtk_button_new_with_label (_("Documentation...")); + gtk_widget_set_name (manual, "manual"); + gtk_widget_ref (manual); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "manual", manual, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (manual); + gtk_container_add (GTK_CONTAINER (doc_hbuttonbox), manual); + STFU GTK_WIDGET_SET_FLAGS (manual, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, manual, _("Click here to read the manual for this display mode, if it has one."), NULL); + + dialog_action_area = GTK_DIALOG (xscreensaver_settings_dialog)->action_area; + gtk_widget_set_name (dialog_action_area, "dialog_action_area"); + gtk_object_set_data (GTK_OBJECT (xscreensaver_settings_dialog), "dialog_action_area", dialog_action_area); + gtk_widget_show (dialog_action_area); + gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area), 10); + + actionarea_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_set_name (actionarea_hbox, "actionarea_hbox"); + gtk_widget_ref (actionarea_hbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "actionarea_hbox", actionarea_hbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (actionarea_hbox); + gtk_box_pack_start (GTK_BOX (dialog_action_area), actionarea_hbox, TRUE, TRUE, 0); + + dialog_hbuttonbox = gtk_hbutton_box_new (); + gtk_widget_set_name (dialog_hbuttonbox, "dialog_hbuttonbox"); + gtk_widget_ref (dialog_hbuttonbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "dialog_hbuttonbox", dialog_hbuttonbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (dialog_hbuttonbox); + gtk_box_pack_start (GTK_BOX (actionarea_hbox), dialog_hbuttonbox, TRUE, TRUE, 0); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_hbuttonbox), GTK_BUTTONBOX_SPREAD); + + adv_button = gtk_button_new_with_label (_("Advanced >>")); + gtk_widget_set_name (adv_button, "adv_button"); + gtk_widget_ref (adv_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "adv_button", adv_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (adv_button); + gtk_container_add (GTK_CONTAINER (dialog_hbuttonbox), adv_button); + STFU GTK_WIDGET_SET_FLAGS (adv_button, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, adv_button, _("Edit the command line directly."), NULL); + + std_button = gtk_button_new_with_label (_("Standard <<")); + gtk_widget_set_name (std_button, "std_button"); + gtk_widget_ref (std_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "std_button", std_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (std_button); + gtk_container_add (GTK_CONTAINER (dialog_hbuttonbox), std_button); + STFU GTK_WIDGET_SET_FLAGS (std_button, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, std_button, _("Back to the graphical configuration options."), NULL); + + reset_button = gtk_button_new_with_label (_("Reset to Defaults")); + gtk_widget_set_name (reset_button, "reset_button"); + gtk_widget_ref (reset_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "reset_button", reset_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (reset_button); + gtk_container_add (GTK_CONTAINER (dialog_hbuttonbox), reset_button); + STFU GTK_WIDGET_SET_FLAGS (reset_button, GTK_CAN_DEFAULT); + gtk_tooltips_set_tip (tooltips, reset_button, _("Reset this screen saver to the default settings."), NULL); + + ok_cancel_hbuttonbox = gtk_hbutton_box_new (); + gtk_widget_set_name (ok_cancel_hbuttonbox, "ok_cancel_hbuttonbox"); + gtk_widget_ref (ok_cancel_hbuttonbox); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "ok_cancel_hbuttonbox", ok_cancel_hbuttonbox, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (ok_cancel_hbuttonbox); + gtk_box_pack_start (GTK_BOX (actionarea_hbox), ok_cancel_hbuttonbox, TRUE, TRUE, 0); + gtk_button_box_set_layout (GTK_BUTTON_BOX (ok_cancel_hbuttonbox), GTK_BUTTONBOX_END); + + ok_button = gtk_button_new_with_label (_("OK")); + gtk_widget_set_name (ok_button, "ok_button"); + gtk_widget_ref (ok_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "ok_button", ok_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (ok_button); + gtk_container_add (GTK_CONTAINER (ok_cancel_hbuttonbox), ok_button); + STFU GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); + + cancel_button = gtk_button_new_with_label (_("Cancel")); + gtk_widget_set_name (cancel_button, "cancel_button"); + gtk_widget_ref (cancel_button); + gtk_object_set_data_full (GTK_OBJECT (xscreensaver_settings_dialog), "cancel_button", cancel_button, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cancel_button); + gtk_container_add (GTK_CONTAINER (ok_cancel_hbuttonbox), cancel_button); + STFU GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); + + gtk_signal_connect (GTK_OBJECT (opt_notebook), "switch_page", + GTK_SIGNAL_FUNC (settings_switch_page_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (manual), "clicked", + GTK_SIGNAL_FUNC (manual_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (adv_button), "clicked", + GTK_SIGNAL_FUNC (settings_adv_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (std_button), "clicked", + GTK_SIGNAL_FUNC (settings_std_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (reset_button), "clicked", + GTK_SIGNAL_FUNC (settings_reset_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (ok_button), "clicked", + GTK_SIGNAL_FUNC (settings_ok_cb), + NULL); + gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked", + GTK_SIGNAL_FUNC (settings_cancel_cb), + NULL); + + gtk_object_set_data (GTK_OBJECT (xscreensaver_settings_dialog), "tooltips", tooltips); + + return xscreensaver_settings_dialog; +} + diff --git a/driver/demo-Gtk-widgets.h b/driver/demo-Gtk-widgets.h new file mode 100644 index 00000000..298c5171 --- /dev/null +++ b/driver/demo-Gtk-widgets.h @@ -0,0 +1,6 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_xscreensaver_demo (void); +GtkWidget* create_xscreensaver_settings_dialog (void); diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c new file mode 100644 index 00000000..fdf239a7 --- /dev/null +++ b/driver/demo-Gtk.c @@ -0,0 +1,5355 @@ +/* demo-Gtk.c --- implements the interactive demo-mode and options dialogs. + * xscreensaver, Copyright (c) 1993-2013 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_GTK /* whole file */ + +#include + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +# ifdef __GNUC__ +# define STFU __extension__ /* ignore gcc -pendantic warnings in next sexp */ +# else +# define STFU /* */ +# endif + + +#ifdef ENABLE_NLS +# include +#endif /* ENABLE_NLS */ + +#ifndef VMS +# include /* for getpwuid() */ +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + +#ifdef HAVE_UNAME +# include /* for uname() */ +#endif /* HAVE_UNAME */ + +#include +#include +#include +#include + + +#include +#include +#ifdef HAVE_SYS_WAIT_H +# include /* for waitpid() and associated macros */ +#endif + + +#include /* for CARD32 */ +#include /* for XA_INTEGER */ +#include +#include + +/* We don't actually use any widget internals, but these are included + so that gdb will have debug info for the widgets... */ +#include +#include + +#ifdef HAVE_XMU +# ifndef VMS +# include +# else /* VMS */ +# include +# endif +#else +# include "xmu.h" +#endif + +#ifdef HAVE_XINERAMA +# include +#endif /* HAVE_XINERAMA */ + +#include + +#ifdef HAVE_CRAPPLET +# include +# include +#endif + +#include + +#ifdef HAVE_GTK2 +# include +# include +#else /* !HAVE_GTK2 */ +# define G_MODULE_EXPORT /**/ +#endif /* !HAVE_GTK2 */ + +#if defined(DEFAULT_ICONDIR) && !defined(GLADE_DIR) +# define GLADE_DIR DEFAULT_ICONDIR +#endif +#if !defined(DEFAULT_ICONDIR) && defined(GLADE_DIR) +# define DEFAULT_ICONDIR GLADE_DIR +#endif + +#ifndef HAVE_XML + /* Kludge: this is defined in demo-Gtk-conf.c when HAVE_XML. + It is unused otherwise, so in that case, stub it out. */ + static const char *hack_configuration_path = 0; +#endif + + + +#include "version.h" +#include "prefs.h" +#include "resources.h" /* for parse_time() */ +#include "visual.h" /* for has_writable_cells() */ +#include "remote.h" /* for xscreensaver_command() */ +#include "usleep.h" + +#include "logo-50.xpm" +#include "logo-180.xpm" + +#undef dgettext /* else these are defined twice... */ +#undef dcgettext + +#include "demo-Gtk-widgets.h" +#include "demo-Gtk-support.h" +#include "demo-Gtk-conf.h" + +#include +#include +#include + +#ifdef HAVE_GTK2 +enum { + COL_ENABLED, + COL_NAME, + COL_LAST +}; +#endif /* HAVE_GTK2 */ + +/* Deal with deprecation of direct access to struct fields on the way to GTK3 + See http://live.gnome.org/GnomeGoals/UseGseal + */ +#if GTK_CHECK_VERSION(2,14,0) +# define GET_PARENT(w) gtk_widget_get_parent (w) +# define GET_WINDOW(w) gtk_widget_get_window (w) +# define GET_ACTION_AREA(d) gtk_dialog_get_action_area (d) +# define GET_CONTENT_AREA(d) gtk_dialog_get_content_area (d) +# define GET_ADJ_VALUE(a) gtk_adjustment_get_value (a) +# define SET_ADJ_VALUE(a,v) gtk_adjustment_set_value (a, v) +# define SET_ADJ_UPPER(a,v) gtk_adjustment_set_upper (a, v) +#else +# define GET_PARENT(w) ((w)->parent) +# define GET_WINDOW(w) ((w)->window) +# define GET_ACTION_AREA(d) ((d)->action_area) +# define GET_CONTENT_AREA(d) ((d)->vbox) +# define GET_ADJ_VALUE(a) ((a)->value) +# define SET_ADJ_VALUE(a,v) (a)->value = v +# define SET_ADJ_UPPER(a,v) (a)->upper = v +#endif + +#if GTK_CHECK_VERSION(2,18,0) +# define SET_CAN_DEFAULT(w) gtk_widget_set_can_default ((w), TRUE) +# define GET_SENSITIVE(w) gtk_widget_get_sensitive (w) +#else +# define SET_CAN_DEFAULT(w) GTK_WIDGET_SET_FLAGS ((w), GTK_CAN_DEFAULT) +# define GET_SENSITIVE(w) GTK_WIDGET_IS_SENSITIVE (w) +#endif + +#if GTK_CHECK_VERSION(2,20,0) +# define GET_REALIZED(w) gtk_widget_get_realized (w) +#else +# define GET_REALIZED(w) GTK_WIDGET_REALIZED (w) +#endif + +/* from exec.c */ +extern void exec_command (const char *shell, const char *command, int nice); +extern int on_path_p (const char *program); + +static void hack_subproc_environment (Window preview_window_id, Bool debug_p); + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + + +/* You might think that to read an array of 32-bit quantities out of a + server-side property, you would pass an array of 32-bit data quantities + into XGetWindowProperty(). You would be wrong. You have to use an array + of longs, even if long is 64 bits (using 32 of each 64.) + */ +typedef long PROP32; + +char *progname = 0; +char *progclass = "XScreenSaver"; +XrmDatabase db; + +/* The order of the items in the mode menu. */ +static int mode_menu_order[] = { + DONT_BLANK, BLANK_ONLY, ONE_HACK, RANDOM_HACKS, RANDOM_HACKS_SAME }; + + +typedef struct { + + char *short_version; /* version number of this xscreensaver build */ + + GtkWidget *toplevel_widget; /* the main window */ + GtkWidget *base_widget; /* root of our hierarchy (for name lookups) */ + GtkWidget *popup_widget; /* the "Settings" dialog */ + conf_data *cdata; /* private data for per-hack configuration */ + +#ifdef HAVE_GTK2 + GladeXML *glade_ui; /* Glade UI file */ +#endif /* HAVE_GTK2 */ + + Bool debug_p; /* whether to print diagnostics */ + Bool initializing_p; /* flag for breaking recursion loops */ + Bool saving_p; /* flag for breaking recursion loops */ + + char *desired_preview_cmd; /* subprocess we intend to run */ + char *running_preview_cmd; /* subprocess we are currently running */ + pid_t running_preview_pid; /* pid of forked subproc (might be dead) */ + Bool running_preview_error_p; /* whether the pid died abnormally */ + + Bool preview_suppressed_p; /* flag meaning "don't launch subproc" */ + int subproc_timer_id; /* timer to delay subproc launch */ + int subproc_check_timer_id; /* timer to check whether it started up */ + int subproc_check_countdown; /* how many more checks left */ + + int *list_elt_to_hack_number; /* table for sorting the hack list */ + int *hack_number_to_list_elt; /* the inverse table */ + Bool *hacks_available_p; /* whether hacks are on $PATH */ + int total_available; /* how many are on $PATH */ + int list_count; /* how many items are in the list: this may be + less than p->screenhacks_count, if some are + suppressed. */ + + int _selected_list_element; /* don't use this: call + selected_list_element() instead */ + + int nscreens; /* How many X or Xinerama screens there are */ + + saver_preferences prefs; + +} state; + + +/* Total fucking evilness due to the fact that it's rocket science to get + a closure object of our own down into the various widget callbacks. */ +static state *global_state_kludge; + +Atom XA_VROOT; +Atom XA_SCREENSAVER, XA_SCREENSAVER_RESPONSE, XA_SCREENSAVER_VERSION; +Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO; +Atom XA_ACTIVATE, XA_BLANK, XA_LOCK, XA_RESTART, XA_EXIT; + + +static void populate_demo_window (state *, int list_elt); +static void populate_prefs_page (state *); +static void populate_popup_window (state *); + +static Bool flush_dialog_changes_and_save (state *); +static Bool flush_popup_changes_and_save (state *); + +static int maybe_reload_init_file (state *); +static void await_xscreensaver (state *); +static Bool xscreensaver_running_p (state *); +static void sensitize_menu_items (state *s, Bool force_p); +static void force_dialog_repaint (state *s); + +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_reset_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); + +static void kill_gnome_screensaver (void); +static void kill_kde_screensaver (void); + + +/* Some random utility functions + */ + +const char *blurb (void); + +const char * +blurb (void) +{ + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + static char buf[255]; + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + + +static GtkWidget * +name_to_widget (state *s, const char *name) +{ + GtkWidget *w; + if (!s) abort(); + if (!name) abort(); + if (!*name) abort(); + +#ifdef HAVE_GTK2 + if (!s->glade_ui) + { + /* First try to load the Glade file from the current directory; + if there isn't one there, check the installed directory. + */ +# define GLADE_FILE_NAME "xscreensaver-demo.glade2" + const char * const files[] = { GLADE_FILE_NAME, + GLADE_DIR "/" GLADE_FILE_NAME }; + int i; + for (i = 0; i < countof (files); i++) + { + struct stat st; + if (!stat (files[i], &st)) + { + s->glade_ui = glade_xml_new (files[i], NULL, NULL); + break; + } + } + if (!s->glade_ui) + { + fprintf (stderr, + "%s: could not load \"" GLADE_FILE_NAME "\"\n" + "\tfrom " GLADE_DIR "/ or current directory.\n", + blurb()); + exit (-1); + } +# undef GLADE_FILE_NAME + + glade_xml_signal_autoconnect (s->glade_ui); + } + + w = glade_xml_get_widget (s->glade_ui, name); + +#else /* !HAVE_GTK2 */ + + w = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (s->base_widget), + name); + if (w) return w; + w = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (s->popup_widget), + name); +#endif /* HAVE_GTK2 */ + if (w) return w; + + fprintf (stderr, "%s: no widget \"%s\" (wrong Glade file?)\n", + blurb(), name); + abort(); +} + + +/* Why this behavior isn't automatic in *either* toolkit, I'll never know. + Takes a scroller, viewport, or list as an argument. + */ +static void +ensure_selected_item_visible (GtkWidget *widget) +{ +#ifdef HAVE_GTK2 + GtkTreePath *path; + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkTreeModel *model; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + path = gtk_tree_path_new_first (); + else + path = gtk_tree_model_get_path (model, &iter); + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path, NULL, FALSE); + + gtk_tree_path_free (path); + +#else /* !HAVE_GTK2 */ + + GtkScrolledWindow *scroller = 0; + GtkViewport *vp = 0; + GtkList *list_widget = 0; + GList *slist; + GList *kids; + int nkids = 0; + GtkWidget *selected = 0; + int list_elt = -1; + GtkAdjustment *adj; + gint parent_h, child_y, child_h, children_h, ignore; + double ratio_t, ratio_b; + + if (GTK_IS_SCROLLED_WINDOW (widget)) + { + scroller = GTK_SCROLLED_WINDOW (widget); + vp = GTK_VIEWPORT (GTK_BIN (scroller)->child); + list_widget = GTK_LIST (GTK_BIN(vp)->child); + } + else if (GTK_IS_VIEWPORT (widget)) + { + vp = GTK_VIEWPORT (widget); + scroller = GTK_SCROLLED_WINDOW (GTK_WIDGET (vp)->parent); + list_widget = GTK_LIST (GTK_BIN(vp)->child); + } + else if (GTK_IS_LIST (widget)) + { + list_widget = GTK_LIST (widget); + vp = GTK_VIEWPORT (GTK_WIDGET (list_widget)->parent); + scroller = GTK_SCROLLED_WINDOW (GTK_WIDGET (vp)->parent); + } + else + abort(); + + slist = list_widget->selection; + selected = (slist ? GTK_WIDGET (slist->data) : 0); + if (!selected) + return; + + list_elt = gtk_list_child_position (list_widget, GTK_WIDGET (selected)); + + for (kids = gtk_container_children (GTK_CONTAINER (list_widget)); + kids; kids = kids->next) + nkids++; + + adj = gtk_scrolled_window_get_vadjustment (scroller); + + gdk_window_get_geometry (GET_WINDOW (GTK_WIDGET (vp)), + &ignore, &ignore, &ignore, &parent_h, &ignore); + gdk_window_get_geometry (GET_WINDOW (GTK_WIDGET (selected)), + &ignore, &child_y, &ignore, &child_h, &ignore); + children_h = nkids * child_h; + + ratio_t = ((double) child_y) / ((double) children_h); + ratio_b = ((double) child_y + child_h) / ((double) children_h); + + if (adj->upper == 0.0) /* no items in list */ + return; + + if (ratio_t < (adj->value / adj->upper) || + ratio_b > ((adj->value + adj->page_size) / adj->upper)) + { + double target; + int slop = parent_h * 0.75; /* how much to overshoot by */ + + if (ratio_t < (adj->value / adj->upper)) + { + double ratio_w = ((double) parent_h) / ((double) children_h); + double ratio_l = (ratio_b - ratio_t); + target = ((ratio_t - ratio_w + ratio_l) * adj->upper); + target += slop; + } + else /* if (ratio_b > ((adj->value + adj->page_size) / adj->upper))*/ + { + target = ratio_t * adj->upper; + target -= slop; + } + + if (target > adj->upper - adj->page_size) + target = adj->upper - adj->page_size; + if (target < 0) + target = 0; + + gtk_adjustment_set_value (adj, target); + } +#endif /* !HAVE_GTK2 */ +} + +static void +warning_dialog_dismiss_cb (GtkWidget *widget, gpointer user_data) +{ + GtkWidget *shell = GTK_WIDGET (user_data); + while (GET_PARENT (shell)) + shell = GET_PARENT (shell); + gtk_widget_destroy (GTK_WIDGET (shell)); +} + + +void restart_menu_cb (GtkWidget *widget, gpointer user_data); + +static void warning_dialog_restart_cb (GtkWidget *widget, gpointer user_data) +{ + restart_menu_cb (widget, user_data); + warning_dialog_dismiss_cb (widget, user_data); +} + +static void warning_dialog_killg_cb (GtkWidget *widget, gpointer user_data) +{ + kill_gnome_screensaver (); + warning_dialog_dismiss_cb (widget, user_data); +} + +static void warning_dialog_killk_cb (GtkWidget *widget, gpointer user_data) +{ + kill_kde_screensaver (); + warning_dialog_dismiss_cb (widget, user_data); +} + +typedef enum { D_NONE, D_LAUNCH, D_GNOME, D_KDE } dialog_button; + +static Bool +warning_dialog (GtkWidget *parent, const char *message, + dialog_button button_type, int center) +{ + char *msg = strdup (message); + char *head; + + GtkWidget *dialog = gtk_dialog_new (); + GtkWidget *label = 0; + GtkWidget *ok = 0; + GtkWidget *cancel = 0; + int i = 0; + + while (parent && !GET_WINDOW (parent)) + parent = GET_PARENT (parent); + + if (!parent || + !GET_WINDOW (parent)) /* too early to pop up transient dialogs */ + { + fprintf (stderr, "%s: too early for dialog?\n", progname); + return False; + } + + head = msg; + while (head) + { + char name[20]; + char *s = strchr (head, '\n'); + if (s) *s = 0; + + sprintf (name, "label%d", i++); + + { + label = gtk_label_new (head); +#ifdef HAVE_GTK2 + gtk_label_set_selectable (GTK_LABEL (label), TRUE); +#endif /* HAVE_GTK2 */ + +#ifndef HAVE_GTK2 + if (i == 1) + { + GTK_WIDGET (label)->style = + gtk_style_copy (GTK_WIDGET (label)->style); + GTK_WIDGET (label)->style->font = + gdk_font_load (get_string_resource("warning_dialog.headingFont", + "Dialog.Font")); + gtk_widget_set_style (GTK_WIDGET (label), + GTK_WIDGET (label)->style); + } +#endif /* !HAVE_GTK2 */ + if (center <= 0) + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (GET_CONTENT_AREA (GTK_DIALOG (dialog))), + label, TRUE, TRUE, 0); + gtk_widget_show (label); + } + + if (s) + head = s+1; + else + head = 0; + + center--; + } + + label = gtk_label_new (""); + gtk_box_pack_start (GTK_BOX (GET_CONTENT_AREA (GTK_DIALOG (dialog))), + label, TRUE, TRUE, 0); + gtk_widget_show (label); + + label = gtk_hbutton_box_new (); + gtk_box_pack_start (GTK_BOX (GET_ACTION_AREA (GTK_DIALOG (dialog))), + label, TRUE, TRUE, 0); + +#ifdef HAVE_GTK2 + if (button_type != D_NONE) + { + cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL); + gtk_container_add (GTK_CONTAINER (label), cancel); + } + + ok = gtk_button_new_from_stock (GTK_STOCK_OK); + gtk_container_add (GTK_CONTAINER (label), ok); + +#else /* !HAVE_GTK2 */ + + ok = gtk_button_new_with_label ("OK"); + gtk_container_add (GTK_CONTAINER (label), ok); + + if (button_type != D_NONE) + { + cancel = gtk_button_new_with_label ("Cancel"); + gtk_container_add (GTK_CONTAINER (label), cancel); + } + +#endif /* !HAVE_GTK2 */ + + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 10); + gtk_window_set_title (GTK_WINDOW (dialog), progclass); + SET_CAN_DEFAULT (ok); + gtk_widget_show (ok); + gtk_widget_grab_focus (ok); + + if (cancel) + { + SET_CAN_DEFAULT (cancel); + gtk_widget_show (cancel); + } + gtk_widget_show (label); + gtk_widget_show (dialog); + + if (button_type != D_NONE) + { + GtkSignalFunc fn; + switch (button_type) { + case D_LAUNCH: fn = GTK_SIGNAL_FUNC (warning_dialog_restart_cb); break; + case D_GNOME: fn = GTK_SIGNAL_FUNC (warning_dialog_killg_cb); break; + case D_KDE: fn = GTK_SIGNAL_FUNC (warning_dialog_killk_cb); break; + default: abort(); break; + } + gtk_signal_connect_object (GTK_OBJECT (ok), "clicked", fn, + (gpointer) dialog); + gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked", + GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb), + (gpointer) dialog); + } + else + { + gtk_signal_connect_object (GTK_OBJECT (ok), "clicked", + GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb), + (gpointer) dialog); + } + + gdk_window_set_transient_for (GET_WINDOW (GTK_WIDGET (dialog)), + GET_WINDOW (GTK_WIDGET (parent))); + +#ifdef HAVE_GTK2 + gtk_window_present (GTK_WINDOW (dialog)); +#else /* !HAVE_GTK2 */ + gdk_window_show (GTK_WIDGET (dialog)->window); + gdk_window_raise (GTK_WIDGET (dialog)->window); +#endif /* !HAVE_GTK2 */ + + free (msg); + return True; +} + + +static void +run_cmd (state *s, Atom command, int arg) +{ + char *err = 0; + int status; + + flush_dialog_changes_and_save (s); + status = xscreensaver_command (GDK_DISPLAY(), command, arg, False, &err); + + /* Kludge: ignore the spurious "window unexpectedly deleted" errors... */ + if (status < 0 && err && strstr (err, "unexpectedly deleted")) + status = 0; + + if (status < 0) + { + char buf [255]; + if (err) + sprintf (buf, "Error:\n\n%s", err); + else + strcpy (buf, "Unknown error!"); + warning_dialog (s->toplevel_widget, buf, D_NONE, 100); + } + if (err) free (err); + + sensitize_menu_items (s, True); + force_dialog_repaint (s); +} + + +static void +run_hack (state *s, int list_elt, Bool report_errors_p) +{ + int hack_number; + char *err = 0; + int status; + + if (list_elt < 0) return; + hack_number = s->list_elt_to_hack_number[list_elt]; + + flush_dialog_changes_and_save (s); + schedule_preview (s, 0); + + status = xscreensaver_command (GDK_DISPLAY(), XA_DEMO, hack_number + 1, + False, &err); + + if (status < 0 && report_errors_p) + { + if (xscreensaver_running_p (s)) + { + /* Kludge: ignore the spurious "window unexpectedly deleted" + errors... */ + if (err && strstr (err, "unexpectedly deleted")) + status = 0; + + if (status < 0) + { + char buf [255]; + if (err) + sprintf (buf, "Error:\n\n%s", err); + else + strcpy (buf, "Unknown error!"); + warning_dialog (s->toplevel_widget, buf, D_NONE, 100); + } + } + else + { + /* The error is that the daemon isn't running; + offer to restart it. + */ + const char *d = DisplayString (GDK_DISPLAY()); + char msg [1024]; + sprintf (msg, + _("Warning:\n\n" + "The XScreenSaver daemon doesn't seem to be running\n" + "on display \"%s\". Launch it now?"), + d); + warning_dialog (s->toplevel_widget, msg, D_LAUNCH, 1); + } + } + + if (err) free (err); + + sensitize_menu_items (s, False); +} + + + +/* Button callbacks + + According to Eric Lassauge, this G_MODULE_EXPORT crud is needed to make + libglade work on Cygwin; apparently all Glade callbacks need this magic + extra declaration. I do not pretend to understand. + */ + +G_MODULE_EXPORT void +exit_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + flush_dialog_changes_and_save (s); + kill_preview_subproc (s, False); + gtk_main_quit (); +} + +static gboolean +wm_toplevel_close_cb (GtkWidget *widget, GdkEvent *event, gpointer data) +{ + state *s = (state *) data; + flush_dialog_changes_and_save (s); + gtk_main_quit (); + return TRUE; +} + + +G_MODULE_EXPORT void +about_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + char msg [2048]; + char *vers = strdup (screensaver_id + 4); + char *s, *s2; + char copy[1024]; + char year[5]; + char *desc = _("For updates, check http://www.jwz.org/xscreensaver/"); + + s = strchr (vers, ','); + *s = 0; + s += 2; + + s2 = vers; + s2 = strrchr (vers, '-'); + s2++; + strncpy (year, s2, 4); + year[4] = 0; + + /* Ole Laursen says "don't use _() here because + non-ASCII characters aren't allowed in localizable string keys." + (I don't want to just use (c) instead of © because that doesn't + look as good in the plain-old default Latin1 "C" locale.) + */ +#ifdef HAVE_GTK2 + sprintf(copy, ("Copyright \xC2\xA9 1991-%s %s"), year, s); +#else /* !HAVE_GTK2 */ + sprintf(copy, ("Copyright \251 1991-%s %s"), year, s); +#endif /* !HAVE_GTK2 */ + + sprintf (msg, "%s\n\n%s", copy, desc); + + /* I can't make gnome_about_new() work here -- it starts dying in + gdk_imlib_get_visual() under gnome_about_new(). If this worked, + then this might be the thing to do: + + #ifdef HAVE_CRAPPLET + { + const gchar *auth[] = { 0 }; + GtkWidget *about = gnome_about_new (progclass, vers, "", auth, desc, + "xscreensaver.xpm"); + gtk_widget_show (about); + } + #else / * GTK but not GNOME * / + ... + */ + { + GdkColormap *colormap; + GdkPixmap *gdkpixmap; + GdkBitmap *mask; + + GtkWidget *dialog = gtk_dialog_new (); + GtkWidget *hbox, *icon, *vbox, *label1, *label2, *hb, *ok; + GtkWidget *parent = GTK_WIDGET (menuitem); + while (GET_PARENT (parent)) + parent = GET_PARENT (parent); + + hbox = gtk_hbox_new (FALSE, 20); + gtk_box_pack_start (GTK_BOX (GET_CONTENT_AREA (GTK_DIALOG (dialog))), + hbox, TRUE, TRUE, 0); + + colormap = gtk_widget_get_colormap (parent); + gdkpixmap = + gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask, NULL, + (gchar **) logo_180_xpm); + icon = gtk_pixmap_new (gdkpixmap, mask); + gtk_misc_set_padding (GTK_MISC (icon), 10, 10); + + gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + + label1 = gtk_label_new (vers); + gtk_box_pack_start (GTK_BOX (vbox), label1, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label1), 0.0, 0.75); + +#ifndef HAVE_GTK2 + GTK_WIDGET (label1)->style = gtk_style_copy (GTK_WIDGET (label1)->style); + GTK_WIDGET (label1)->style->font = + gdk_font_load (get_string_resource ("about.headingFont","Dialog.Font")); + gtk_widget_set_style (GTK_WIDGET (label1), GTK_WIDGET (label1)->style); +#endif /* HAVE_GTK2 */ + + label2 = gtk_label_new (msg); + gtk_box_pack_start (GTK_BOX (vbox), label2, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label2), 0.0, 0.25); + +#ifndef HAVE_GTK2 + GTK_WIDGET (label2)->style = gtk_style_copy (GTK_WIDGET (label2)->style); + GTK_WIDGET (label2)->style->font = + gdk_font_load (get_string_resource ("about.bodyFont","Dialog.Font")); + gtk_widget_set_style (GTK_WIDGET (label2), GTK_WIDGET (label2)->style); +#endif /* HAVE_GTK2 */ + + hb = gtk_hbutton_box_new (); + + gtk_box_pack_start (GTK_BOX (GET_ACTION_AREA (GTK_DIALOG (dialog))), + hb, TRUE, TRUE, 0); + +#ifdef HAVE_GTK2 + ok = gtk_button_new_from_stock (GTK_STOCK_OK); +#else /* !HAVE_GTK2 */ + ok = gtk_button_new_with_label (_("OK")); +#endif /* !HAVE_GTK2 */ + gtk_container_add (GTK_CONTAINER (hb), ok); + + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 10); + gtk_window_set_title (GTK_WINDOW (dialog), progclass); + + gtk_widget_show (hbox); + gtk_widget_show (icon); + gtk_widget_show (vbox); + gtk_widget_show (label1); + gtk_widget_show (label2); + gtk_widget_show (hb); + gtk_widget_show (ok); + gtk_widget_show (dialog); + + gtk_signal_connect_object (GTK_OBJECT (ok), "clicked", + GTK_SIGNAL_FUNC (warning_dialog_dismiss_cb), + (gpointer) dialog); + gdk_window_set_transient_for (GET_WINDOW (GTK_WIDGET (dialog)), + GET_WINDOW (GTK_WIDGET (parent))); + gdk_window_show (GET_WINDOW (GTK_WIDGET (dialog))); + gdk_window_raise (GET_WINDOW (GTK_WIDGET (dialog))); + } +} + + +G_MODULE_EXPORT void +doc_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + saver_preferences *p = &s->prefs; + char *help_command; + + if (!p->help_url || !*p->help_url) + { + warning_dialog (s->toplevel_widget, + _("Error:\n\n" + "No Help URL has been specified.\n"), D_NONE, 100); + return; + } + + help_command = (char *) malloc (strlen (p->load_url_command) + + (strlen (p->help_url) * 4) + 20); + strcpy (help_command, "( "); + sprintf (help_command + strlen(help_command), + p->load_url_command, + p->help_url, p->help_url, p->help_url, p->help_url); + strcat (help_command, " ) &"); + if (system (help_command) < 0) + fprintf (stderr, "%s: fork error\n", blurb()); + free (help_command); +} + + +G_MODULE_EXPORT void +file_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + sensitize_menu_items (s, False); +} + + +G_MODULE_EXPORT void +activate_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + run_cmd (s, XA_ACTIVATE, 0); +} + + +G_MODULE_EXPORT void +lock_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + run_cmd (s, XA_LOCK, 0); +} + + +G_MODULE_EXPORT void +kill_menu_cb (GtkMenuItem *menuitem, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + run_cmd (s, XA_EXIT, 0); +} + + +G_MODULE_EXPORT void +restart_menu_cb (GtkWidget *widget, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + flush_dialog_changes_and_save (s); + xscreensaver_command (GDK_DISPLAY(), XA_EXIT, 0, False, NULL); + sleep (1); + if (system ("xscreensaver -nosplash &") < 0) + fprintf (stderr, "%s: fork error\n", blurb()); + + await_xscreensaver (s); +} + +static Bool +xscreensaver_running_p (state *s) +{ + Display *dpy = GDK_DISPLAY(); + char *rversion = 0; + server_xscreensaver_version (dpy, &rversion, 0, 0); + if (!rversion) + return False; + free (rversion); + return True; +} + +static void +await_xscreensaver (state *s) +{ + int countdown = 5; + Bool ok = False; + + while (!ok && (--countdown > 0)) + if (xscreensaver_running_p (s)) + ok = True; + else + sleep (1); /* If it's not there yet, wait a second... */ + + sensitize_menu_items (s, True); + + if (! ok) + { + /* Timed out, no screensaver running. */ + + char buf [1024]; + Bool root_p = (geteuid () == 0); + + strcpy (buf, + _("Error:\n\n" + "The xscreensaver daemon did not start up properly.\n" + "\n")); + + if (root_p) + +# ifdef __GNUC__ + __extension__ /* don't warn about "string length is greater than + the length ISO C89 compilers are required to + support" in the following expression... */ +# endif + strcat (buf, STFU + _("You are running as root. This usually means that xscreensaver\n" + "was unable to contact your X server because access control is\n" + "turned on. Try running this command:\n" + "\n" + " xhost +localhost\n" + "\n" + "and then selecting `File / Restart Daemon'.\n" + "\n" + "Note that turning off access control will allow anyone logged\n" + "on to this machine to access your screen, which might be\n" + "considered a security problem. Please read the xscreensaver\n" + "manual and FAQ for more information.\n" + "\n" + "You shouldn't run X as root. Instead, you should log in as a\n" + "normal user, and `su' as necessary.")); + else + strcat (buf, _("Please check your $PATH and permissions.")); + + warning_dialog (s->toplevel_widget, buf, D_NONE, 1); + } + + force_dialog_repaint (s); +} + + +static int +selected_list_element (state *s) +{ + return s->_selected_list_element; +} + + +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... */ + if (strcmp (s->prefs.screenhacks[0]->name, "DNA Lounge Slideshow")) + abort(); +#endif + + if (!write_init_file (dpy, p, s->short_version, False)) + { + if (s->debug_p) + fprintf (stderr, "%s: wrote %s\n", blurb(), init_file_name()); + return 0; + } + else + { + const char *f = init_file_name(); + if (!f || !*f) + warning_dialog (s->toplevel_widget, + _("Error:\n\nCouldn't determine init file name!\n"), + D_NONE, 100); + else + { + char *b = (char *) malloc (strlen(f) + 1024); + sprintf (b, _("Error:\n\nCouldn't write %s\n"), f); + warning_dialog (s->toplevel_widget, b, D_NONE, 100); + free (b); + } + return -1; + } +} + + +G_MODULE_EXPORT void +run_this_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + int list_elt = selected_list_element (s); + if (list_elt < 0) return; + if (!flush_dialog_changes_and_save (s)) + run_hack (s, list_elt, True); +} + + +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"); + int list_elt = selected_list_element (s); + int hack_number; + char *name, *name2, *cmd, *str; + char *oname = 0; + if (list_elt < 0) return; + hack_number = s->list_elt_to_hack_number[list_elt]; + + flush_dialog_changes_and_save (s); + ensure_selected_item_visible (list_widget); + + name = strdup (p->screenhacks[hack_number]->command); + name2 = name; + oname = name; + while (isspace (*name2)) name2++; + str = name2; + while (*str && !isspace (*str)) str++; + *str = 0; + str = strrchr (name2, '/'); + if (str) name2 = str+1; + + cmd = get_string_resource (dpy, "manualCommand", "ManualCommand"); + if (cmd) + { + char *cmd2 = (char *) malloc (strlen (cmd) + (strlen (name2) * 4) + 100); + strcpy (cmd2, "( "); + sprintf (cmd2 + strlen (cmd2), + cmd, + name2, name2, name2, name2); + strcat (cmd2, " ) &"); + if (system (cmd2) < 0) + fprintf (stderr, "%s: fork error\n", blurb()); + free (cmd2); + } + else + { + warning_dialog (GTK_WIDGET (button), + _("Error:\n\nno `manualCommand' resource set."), + D_NONE, 100); + } + + free (oname); +} + + +static void +force_list_select_item (state *s, GtkWidget *list, int list_elt, Bool scroll_p) +{ + GtkWidget *parent = name_to_widget (s, "scroller"); + gboolean was = GET_SENSITIVE (parent); +#ifdef HAVE_GTK2 + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeSelection *selection; +#endif /* HAVE_GTK2 */ + + if (!was) gtk_widget_set_sensitive (parent, True); +#ifdef HAVE_GTK2 + model = gtk_tree_view_get_model (GTK_TREE_VIEW (list)); + g_assert (model); + if (gtk_tree_model_iter_nth_child (model, &iter, NULL, list_elt)) + { + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list)); + gtk_tree_selection_select_iter (selection, &iter); + } +#else /* !HAVE_GTK2 */ + gtk_list_select_item (GTK_LIST (list), list_elt); +#endif /* !HAVE_GTK2 */ + if (scroll_p) ensure_selected_item_visible (GTK_WIDGET (list)); + if (!was) gtk_widget_set_sensitive (parent, False); +} + + +G_MODULE_EXPORT void +run_next_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + /* saver_preferences *p = &s->prefs; */ + Bool ops = s->preview_suppressed_p; + + GtkWidget *list_widget = name_to_widget (s, "list"); + int list_elt = selected_list_element (s); + + if (list_elt < 0) + list_elt = 0; + else + list_elt++; + + if (list_elt >= s->list_count) + list_elt = 0; + + s->preview_suppressed_p = True; + + flush_dialog_changes_and_save (s); + force_list_select_item (s, list_widget, list_elt, True); + populate_demo_window (s, list_elt); + run_hack (s, list_elt, False); + + s->preview_suppressed_p = ops; +} + + +G_MODULE_EXPORT void +run_prev_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + /* saver_preferences *p = &s->prefs; */ + Bool ops = s->preview_suppressed_p; + + GtkWidget *list_widget = name_to_widget (s, "list"); + int list_elt = selected_list_element (s); + + if (list_elt < 0) + list_elt = s->list_count - 1; + else + list_elt--; + + if (list_elt < 0) + list_elt = s->list_count - 1; + + s->preview_suppressed_p = True; + + flush_dialog_changes_and_save (s); + force_list_select_item (s, list_widget, list_elt, True); + populate_demo_window (s, list_elt); + run_hack (s, list_elt, False); + + s->preview_suppressed_p = ops; +} + + +/* Writes the given settings into prefs. + Returns true if there was a change, False otherwise. + command and/or visual may be 0, or enabled_p may be -1, meaning "no change". + */ +static Bool +flush_changes (state *s, + int list_elt, + int enabled_p, + const char *command, + const char *visual) +{ + saver_preferences *p = &s->prefs; + Bool changed = False; + screenhack *hack; + int hack_number; + if (list_elt < 0 || list_elt >= s->list_count) + abort(); + + hack_number = s->list_elt_to_hack_number[list_elt]; + hack = p->screenhacks[hack_number]; + + if (enabled_p != -1 && + enabled_p != hack->enabled_p) + { + hack->enabled_p = enabled_p; + changed = True; + if (s->debug_p) + fprintf (stderr, "%s: \"%s\": enabled => %d\n", + blurb(), hack->name, enabled_p); + } + + if (command) + { + if (!hack->command || !!strcmp (command, hack->command)) + { + if (hack->command) free (hack->command); + hack->command = strdup (command); + changed = True; + if (s->debug_p) + fprintf (stderr, "%s: \"%s\": command => \"%s\"\n", + blurb(), hack->name, command); + } + } + + if (visual) + { + const char *ov = hack->visual; + if (!ov || !*ov) ov = "any"; + if (!*visual) visual = "any"; + if (!!strcasecmp (visual, ov)) + { + if (hack->visual) free (hack->visual); + hack->visual = strdup (visual); + changed = True; + if (s->debug_p) + fprintf (stderr, "%s: \"%s\": visual => \"%s\"\n", + blurb(), hack->name, visual); + } + } + + return changed; +} + + +/* Helper for the text fields that contain time specifications: + this parses the text, and does error checking. + */ +static void +hack_time_text (state *s, const char *line, Time *store, Bool sec_p) +{ + if (*line) + { + int value; + if (!sec_p || strchr (line, ':')) + value = parse_time ((char *) line, sec_p, True); + else + { + char c; + if (sscanf (line, "%d%c", &value, &c) != 1) + value = -1; + if (!sec_p) + value *= 60; + } + + value *= 1000; /* Time measures in microseconds */ + if (value < 0) + { + char b[255]; + sprintf (b, + _("Error:\n\n" + "Unparsable time format: \"%s\"\n"), + line); + warning_dialog (s->toplevel_widget, b, D_NONE, 100); + } + else + *store = value; + } +} + + +static Bool +directory_p (const char *path) +{ + struct stat st; + if (!path || !*path) + return False; + else if (stat (path, &st)) + return False; + else if (!S_ISDIR (st.st_mode)) + return False; + else + return True; +} + +static Bool +file_p (const char *path) +{ + struct stat st; + if (!path || !*path) + return False; + else if (stat (path, &st)) + return False; + else if (S_ISDIR (st.st_mode)) + return False; + else + return True; +} + +static char * +normalize_directory (const char *path) +{ + int L; + char *p2, *s; + if (!path || !*path) return 0; + L = strlen (path); + p2 = (char *) malloc (L + 2); + strcpy (p2, path); + if (p2[L-1] == '/') /* remove trailing slash */ + p2[--L] = 0; + + for (s = p2; s && *s; s++) + { + if (*s == '/' && + (!strncmp (s, "/../", 4) || /* delete "XYZ/../" */ + !strncmp (s, "/..\000", 4))) /* delete "XYZ/..$" */ + { + char *s0 = s; + while (s0 > p2 && s0[-1] != '/') + s0--; + if (s0 > p2) + { + s0--; + s += 3; + /* strcpy (s0, s); */ + memmove(s0, s, strlen(s) + 1); + s = s0-1; + } + } + else if (*s == '/' && !strncmp (s, "/./", 3)) { /* delete "/./" */ + /* strcpy (s, s+2), s--; */ + memmove(s, s+2, strlen(s+2) + 1); + s--; + } + else if (*s == '/' && !strncmp (s, "/.\000", 3)) /* delete "/.$" */ + *s = 0, s--; + } + + /* + Normalize consecutive slashes. + Ignore doubled slashes after ":" to avoid mangling URLs. + */ + + for (s = p2; s && *s; s++){ + if (*s == ':') continue; + if (!s[1] || !s[2]) continue; + while (s[1] == '/' && s[2] == '/') + /* strcpy (s+1, s+2); */ + memmove (s+1, s+2, strlen(s+2) + 1); + } + + /* and strip trailing whitespace for good measure. */ + L = strlen(p2); + while (isspace(p2[L-1])) + p2[--L] = 0; + + return p2; +} + + +#ifdef HAVE_GTK2 + +typedef struct { + state *s; + int i; + Bool *changed; +} FlushForeachClosure; + +static gboolean +flush_checkbox (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + FlushForeachClosure *closure = data; + gboolean checked; + + gtk_tree_model_get (model, iter, + COL_ENABLED, &checked, + -1); + + if (flush_changes (closure->s, closure->i, + checked, 0, 0)) + *closure->changed = True; + + closure->i++; + + /* don't remove row */ + return FALSE; +} + +#endif /* HAVE_GTK2 */ + +/* Flush out any changes made in the main dialog window (where changes + take place immediately: clicking on a checkbox causes the init file + to be written right away.) + */ +static Bool +flush_dialog_changes_and_save (state *s) +{ + saver_preferences *p = &s->prefs; + saver_preferences P2, *p2 = &P2; +#ifdef HAVE_GTK2 + GtkTreeView *list_widget = GTK_TREE_VIEW (name_to_widget (s, "list")); + GtkTreeModel *model = gtk_tree_view_get_model (list_widget); + FlushForeachClosure closure; +#else /* !HAVE_GTK2 */ + GtkList *list_widget = GTK_LIST (name_to_widget (s, "list")); + GList *kids = gtk_container_children (GTK_CONTAINER (list_widget)); + int i; +#endif /* !HAVE_GTK2 */ + static Bool already_warned_about_missing_image_directory = False; /* very long name... */ + + Bool changed = False; + GtkWidget *w; + + if (s->saving_p) return False; + s->saving_p = True; + + *p2 = *p; + + /* Flush any checkbox changes in the list down into the prefs struct. + */ +#ifdef HAVE_GTK2 + closure.s = s; + closure.changed = &changed; + closure.i = 0; + gtk_tree_model_foreach (model, flush_checkbox, &closure); + +#else /* !HAVE_GTK2 */ + + for (i = 0; kids; kids = kids->next, i++) + { + GtkWidget *line = GTK_WIDGET (kids->data); + GtkWidget *line_hbox = GTK_WIDGET (GTK_BIN (line)->child); + GtkWidget *line_check = + GTK_WIDGET (gtk_container_children (GTK_CONTAINER (line_hbox))->data); + Bool checked = + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (line_check)); + + if (flush_changes (s, i, (checked ? 1 : 0), 0, 0)) + changed = True; + } +#endif /* ~HAVE_GTK2 */ + + /* Flush the non-hack-specific settings down into the prefs struct. + */ + +# define SECONDS(FIELD,NAME) \ + w = name_to_widget (s, (NAME)); \ + hack_time_text (s, gtk_entry_get_text (GTK_ENTRY (w)), (FIELD), True) + +# define MINUTES(FIELD,NAME) \ + w = name_to_widget (s, (NAME)); \ + hack_time_text (s, gtk_entry_get_text (GTK_ENTRY (w)), (FIELD), False) + +# define CHECKBOX(FIELD,NAME) \ + w = name_to_widget (s, (NAME)); \ + (FIELD) = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)) + +# define PATHNAME(FIELD,NAME) \ + w = name_to_widget (s, (NAME)); \ + (FIELD) = normalize_directory (gtk_entry_get_text (GTK_ENTRY (w))) + +# define TEXT(FIELD,NAME) \ + w = name_to_widget (s, (NAME)); \ + (FIELD) = (char *) gtk_entry_get_text (GTK_ENTRY (w)) + + MINUTES (&p2->timeout, "timeout_spinbutton"); + MINUTES (&p2->cycle, "cycle_spinbutton"); + CHECKBOX (p2->lock_p, "lock_button"); + MINUTES (&p2->lock_timeout, "lock_spinbutton"); + + CHECKBOX (p2->dpms_enabled_p, "dpms_button"); + CHECKBOX (p2->dpms_quickoff_p, "dpms_quickoff_button"); + MINUTES (&p2->dpms_standby, "dpms_standby_spinbutton"); + MINUTES (&p2->dpms_suspend, "dpms_suspend_spinbutton"); + MINUTES (&p2->dpms_off, "dpms_off_spinbutton"); + + CHECKBOX (p2->grab_desktop_p, "grab_desk_button"); + CHECKBOX (p2->grab_video_p, "grab_video_button"); + CHECKBOX (p2->random_image_p, "grab_image_button"); + PATHNAME (p2->image_directory, "image_text"); + +#if 0 + CHECKBOX (p2->verbose_p, "verbose_button"); + CHECKBOX (p2->capture_stderr_p, "capture_button"); + CHECKBOX (p2->splash_p, "splash_button"); +#endif + + { + Bool v = False; + CHECKBOX (v, "text_host_radio"); if (v) p2->tmode = TEXT_DATE; + CHECKBOX (v, "text_radio"); if (v) p2->tmode = TEXT_LITERAL; + CHECKBOX (v, "text_file_radio"); if (v) p2->tmode = TEXT_FILE; + CHECKBOX (v, "text_program_radio"); if (v) p2->tmode = TEXT_PROGRAM; + CHECKBOX (v, "text_url_radio"); if (v) p2->tmode = TEXT_URL; + TEXT (p2->text_literal, "text_entry"); + PATHNAME (p2->text_file, "text_file_entry"); + PATHNAME (p2->text_program, "text_program_entry"); + PATHNAME (p2->text_program, "text_program_entry"); + TEXT (p2->text_url, "text_url_entry"); + } + + CHECKBOX (p2->install_cmap_p, "install_button"); + CHECKBOX (p2->fade_p, "fade_button"); + CHECKBOX (p2->unfade_p, "unfade_button"); + SECONDS (&p2->fade_seconds, "fade_spinbutton"); + +# undef SECONDS +# undef MINUTES +# undef CHECKBOX +# undef PATHNAME +# undef TEXT + + /* Warn if the image directory doesn't exist, when: + - not being warned before + - image directory is changed and the directory doesn't exist + - image directory does not begin with http:// + */ + if (p2->image_directory && + *p2->image_directory && + !directory_p (p2->image_directory) && + strncmp(p2->image_directory, "http://", 6) && + ( !already_warned_about_missing_image_directory || + ( p->image_directory && + *p->image_directory && + strcmp(p->image_directory, p2->image_directory) + ) + ) + ) + { + char b[255]; + sprintf (b, "Warning:\n\n" "Directory does not exist: \"%s\"\n", + p2->image_directory); + if (warning_dialog (s->toplevel_widget, b, D_NONE, 100)) + already_warned_about_missing_image_directory = True; + } + + + /* Map the mode menu to `saver_mode' enum values. */ + { + GtkOptionMenu *opt = GTK_OPTION_MENU (name_to_widget (s, "mode_menu")); + GtkMenu *menu = GTK_MENU (gtk_option_menu_get_menu (opt)); + GtkWidget *selected = gtk_menu_get_active (menu); + GList *kids = gtk_container_children (GTK_CONTAINER (menu)); + int menu_elt = g_list_index (kids, (gpointer) selected); + if (menu_elt < 0 || menu_elt >= countof(mode_menu_order)) abort(); + p2->mode = mode_menu_order[menu_elt]; + } + + if (p2->mode == ONE_HACK) + { + int list_elt = selected_list_element (s); + p2->selected_hack = (list_elt >= 0 + ? s->list_elt_to_hack_number[list_elt] + : -1); + } + +# define COPY(field, name) \ + if (p->field != p2->field) { \ + changed = True; \ + if (s->debug_p) \ + fprintf (stderr, "%s: %s => %d\n", blurb(), name, (int) p2->field); \ + } \ + p->field = p2->field + + COPY(mode, "mode"); + COPY(selected_hack, "selected_hack"); + + COPY(timeout, "timeout"); + COPY(cycle, "cycle"); + COPY(lock_p, "lock_p"); + COPY(lock_timeout, "lock_timeout"); + + COPY(dpms_enabled_p, "dpms_enabled_p"); + COPY(dpms_quickoff_p, "dpms_quickoff_enabled_p"); + COPY(dpms_standby, "dpms_standby"); + COPY(dpms_suspend, "dpms_suspend"); + COPY(dpms_off, "dpms_off"); + +#if 0 + COPY(verbose_p, "verbose_p"); + COPY(capture_stderr_p, "capture_stderr_p"); + COPY(splash_p, "splash_p"); +#endif + + COPY(tmode, "tmode"); + + COPY(install_cmap_p, "install_cmap_p"); + COPY(fade_p, "fade_p"); + COPY(unfade_p, "unfade_p"); + COPY(fade_seconds, "fade_seconds"); + + COPY(grab_desktop_p, "grab_desktop_p"); + COPY(grab_video_p, "grab_video_p"); + COPY(random_image_p, "random_image_p"); + +# undef COPY + +# define COPYSTR(FIELD,NAME) \ + if (!p->FIELD || \ + !p2->FIELD || \ + strcmp(p->FIELD, p2->FIELD)) \ + { \ + changed = True; \ + if (s->debug_p) \ + fprintf (stderr, "%s: %s => \"%s\"\n", blurb(), NAME, p2->FIELD); \ + } \ + if (p->FIELD && p->FIELD != p2->FIELD) \ + free (p->FIELD); \ + p->FIELD = p2->FIELD; \ + p2->FIELD = 0 + + COPYSTR(image_directory, "image_directory"); + COPYSTR(text_literal, "text_literal"); + COPYSTR(text_file, "text_file"); + COPYSTR(text_program, "text_program"); + COPYSTR(text_url, "text_url"); +# undef COPYSTR + + populate_prefs_page (s); + + if (changed) + { + Display *dpy = GDK_DISPLAY(); + Bool enabled_p = (p->dpms_enabled_p && p->mode != DONT_BLANK); + sync_server_dpms_settings (dpy, enabled_p, + p->dpms_standby / 1000, + p->dpms_suspend / 1000, + p->dpms_off / 1000, + False); + + changed = demo_write_init_file (s, p); + } + + s->saving_p = False; + return changed; +} + + +/* Flush out any changes made in the popup dialog box (where changes + take place only when the OK button is clicked.) + */ +static Bool +flush_popup_changes_and_save (state *s) +{ + Bool changed = False; + saver_preferences *p = &s->prefs; + int list_elt = selected_list_element (s); + + GtkEntry *cmd = GTK_ENTRY (name_to_widget (s, "cmd_text")); + GtkCombo *vis = GTK_COMBO (name_to_widget (s, "visual_combo")); + + const char *visual = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (vis)->entry)); + const char *command = gtk_entry_get_text (cmd); + + char c; + unsigned long id; + + if (s->saving_p) return False; + s->saving_p = True; + + if (list_elt < 0) + goto DONE; + + if (maybe_reload_init_file (s) != 0) + { + changed = True; + goto DONE; + } + + /* Sanity-check and canonicalize whatever the user typed into the combo box. + */ + if (!strcasecmp (visual, "")) visual = ""; + else if (!strcasecmp (visual, "any")) visual = ""; + else if (!strcasecmp (visual, "default")) visual = "Default"; + else if (!strcasecmp (visual, "default-n")) visual = "Default-N"; + else if (!strcasecmp (visual, "default-i")) visual = "Default-I"; + else if (!strcasecmp (visual, "best")) visual = "Best"; + else if (!strcasecmp (visual, "mono")) visual = "Mono"; + else if (!strcasecmp (visual, "monochrome")) visual = "Mono"; + else if (!strcasecmp (visual, "gray")) visual = "Gray"; + else if (!strcasecmp (visual, "grey")) visual = "Gray"; + else if (!strcasecmp (visual, "color")) visual = "Color"; + else if (!strcasecmp (visual, "gl")) visual = "GL"; + else if (!strcasecmp (visual, "staticgray")) visual = "StaticGray"; + else if (!strcasecmp (visual, "staticcolor")) visual = "StaticColor"; + else if (!strcasecmp (visual, "truecolor")) visual = "TrueColor"; + else if (!strcasecmp (visual, "grayscale")) visual = "GrayScale"; + else if (!strcasecmp (visual, "greyscale")) visual = "GrayScale"; + else if (!strcasecmp (visual, "pseudocolor")) visual = "PseudoColor"; + else if (!strcasecmp (visual, "directcolor")) visual = "DirectColor"; + else if (1 == sscanf (visual, " %lu %c", &id, &c)) ; + else if (1 == sscanf (visual, " 0x%lx %c", &id, &c)) ; + else + { + gdk_beep (); /* unparsable */ + visual = ""; + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry), _("Any")); + } + + changed = flush_changes (s, list_elt, -1, command, visual); + if (changed) + { + changed = demo_write_init_file (s, p); + + /* Do this to re-launch the hack if (and only if) the command line + has changed. */ + populate_demo_window (s, selected_list_element (s)); + } + + DONE: + s->saving_p = False; + return changed; +} + + +G_MODULE_EXPORT void +pref_changed_cb (GtkWidget *widget, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + if (! s->initializing_p) + { + s->initializing_p = True; + flush_dialog_changes_and_save (s); + s->initializing_p = False; + } +} + +G_MODULE_EXPORT gboolean +pref_changed_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + pref_changed_cb (widget, user_data); + return FALSE; +} + +/* Callback on menu items in the "mode" options menu. + */ +G_MODULE_EXPORT void +mode_menu_item_cb (GtkWidget *widget, gpointer user_data) +{ + state *s = (state *) user_data; + saver_preferences *p = &s->prefs; + GtkWidget *list = name_to_widget (s, "list"); + int list_elt; + + GList *menu_items = + gtk_container_children (GTK_CONTAINER (GET_PARENT (widget))); + int menu_index = 0; + saver_mode new_mode; + + while (menu_items) + { + if (menu_items->data == widget) + break; + menu_index++; + menu_items = menu_items->next; + } + if (!menu_items) abort(); + + new_mode = mode_menu_order[menu_index]; + + /* Keep the same list element displayed as before; except if we're + switching *to* "one screensaver" mode from any other mode, set + "the one" to be that which is currently selected. + */ + list_elt = selected_list_element (s); + if (new_mode == ONE_HACK) + p->selected_hack = s->list_elt_to_hack_number[list_elt]; + + { + saver_mode old_mode = p->mode; + p->mode = new_mode; + populate_demo_window (s, list_elt); + force_list_select_item (s, list, list_elt, True); + p->mode = old_mode; /* put it back, so the init file gets written */ + } + + pref_changed_cb (widget, user_data); +} + + +G_MODULE_EXPORT void +switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page, + gint page_num, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + pref_changed_cb (GTK_WIDGET (notebook), user_data); + + /* If we're switching to page 0, schedule the current hack to be run. + Otherwise, schedule it to stop. */ + if (page_num == 0) + populate_demo_window (s, selected_list_element (s)); + else + schedule_preview (s, 0); +} + +#ifdef HAVE_GTK2 +static void +list_activated_cb (GtkTreeView *list, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer data) +{ + state *s = data; + char *str; + int list_elt; + + g_return_if_fail (!gdk_pointer_is_grabbed ()); + + str = gtk_tree_path_to_string (path); + list_elt = strtol (str, NULL, 10); + g_free (str); + + if (list_elt >= 0) + run_hack (s, list_elt, True); +} + +static void +list_select_changed_cb (GtkTreeSelection *selection, gpointer data) +{ + state *s = (state *)data; + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreePath *path; + char *str; + int list_elt; + + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + + path = gtk_tree_model_get_path (model, &iter); + str = gtk_tree_path_to_string (path); + list_elt = strtol (str, NULL, 10); + + gtk_tree_path_free (path); + g_free (str); + + populate_demo_window (s, list_elt); + flush_dialog_changes_and_save (s); + + /* Re-populate the Settings window any time a new item is selected + in the list, in case both windows are currently visible. + */ + populate_popup_window (s); +} + +#else /* !HAVE_GTK2 */ + +static time_t last_doubleclick_time = 0; /* FMH! This is to suppress the + list_select_cb that comes in + *after* we've double-clicked. + */ + +static gint +list_doubleclick_cb (GtkWidget *button, GdkEventButton *event, + gpointer data) +{ + state *s = (state *) data; + if (event->type == GDK_2BUTTON_PRESS) + { + GtkList *list = GTK_LIST (name_to_widget (s, "list")); + int list_elt = gtk_list_child_position (list, GTK_WIDGET (button)); + + last_doubleclick_time = time ((time_t *) 0); + + if (list_elt >= 0) + run_hack (s, list_elt, True); + } + + return FALSE; +} + + +static void +list_select_cb (GtkList *list, GtkWidget *child, gpointer data) +{ + state *s = (state *) data; + time_t now = time ((time_t *) 0); + + if (now >= last_doubleclick_time + 2) + { + int list_elt = gtk_list_child_position (list, GTK_WIDGET (child)); + populate_demo_window (s, list_elt); + flush_dialog_changes_and_save (s); + } +} + +static void +list_unselect_cb (GtkList *list, GtkWidget *child, gpointer data) +{ + state *s = (state *) data; + populate_demo_window (s, -1); + flush_dialog_changes_and_save (s); +} + +#endif /* !HAVE_GTK2 */ + + +/* Called when the checkboxes that are in the left column of the + scrolling list are clicked. This both populates the right pane + (just as clicking on the label (really, listitem) does) and + also syncs this checkbox with the right pane Enabled checkbox. + */ +static void +list_checkbox_cb ( +#ifdef HAVE_GTK2 + GtkCellRendererToggle *toggle, + gchar *path_string, +#else /* !HAVE_GTK2 */ + GtkWidget *cb, +#endif /* !HAVE_GTK2 */ + gpointer data) +{ + state *s = (state *) data; + +#ifdef HAVE_GTK2 + GtkScrolledWindow *scroller = + GTK_SCROLLED_WINDOW (name_to_widget (s, "scroller")); + GtkTreeView *list = GTK_TREE_VIEW (name_to_widget (s, "list")); + GtkTreeModel *model = gtk_tree_view_get_model (list); + GtkTreePath *path = gtk_tree_path_new_from_string (path_string); + GtkTreeIter iter; + gboolean active; +#else /* !HAVE_GTK2 */ + GtkWidget *line_hbox = GTK_WIDGET (cb)->parent; + GtkWidget *line = GTK_WIDGET (line_hbox)->parent; + + GtkList *list = GTK_LIST (GTK_WIDGET (line)->parent); + GtkViewport *vp = GTK_VIEWPORT (GTK_WIDGET (list)->parent); + GtkScrolledWindow *scroller = GTK_SCROLLED_WINDOW (GTK_WIDGET (vp)->parent); +#endif /* !HAVE_GTK2 */ + GtkAdjustment *adj; + double scroll_top; + + int list_elt; + +#ifdef HAVE_GTK2 + if (!gtk_tree_model_get_iter (model, &iter, path)) + { + g_warning ("bad path: %s", path_string); + return; + } + gtk_tree_path_free (path); + + gtk_tree_model_get (model, &iter, + COL_ENABLED, &active, + -1); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_ENABLED, !active, + -1); + + list_elt = strtol (path_string, NULL, 10); +#else /* !HAVE_GTK2 */ + list_elt = gtk_list_child_position (list, line); +#endif /* !HAVE_GTK2 */ + + /* remember previous scroll position of the top of the list */ + adj = gtk_scrolled_window_get_vadjustment (scroller); + scroll_top = GET_ADJ_VALUE (adj); + + flush_dialog_changes_and_save (s); + force_list_select_item (s, GTK_WIDGET (list), list_elt, False); + populate_demo_window (s, list_elt); + + /* restore the previous scroll position of the top of the list. + this is weak, but I don't really know why it's moving... */ + gtk_adjustment_set_value (adj, scroll_top); +} + + +typedef struct { + state *state; + GtkFileSelection *widget; +} file_selection_data; + + + +static void +store_image_directory (GtkWidget *button, gpointer user_data) +{ + file_selection_data *fsd = (file_selection_data *) user_data; + state *s = fsd->state; + GtkFileSelection *selector = fsd->widget; + GtkWidget *top = s->toplevel_widget; + saver_preferences *p = &s->prefs; + const char *path = gtk_file_selection_get_filename (selector); + + if (p->image_directory && !strcmp(p->image_directory, path)) + return; /* no change */ + + /* No warning for URLs. */ + if ((!directory_p (path)) && strncmp(path, "http://", 6)) + { + char b[255]; + sprintf (b, _("Error:\n\n" "Directory does not exist: \"%s\"\n"), path); + warning_dialog (GTK_WIDGET (top), b, D_NONE, 100); + return; + } + + if (p->image_directory) free (p->image_directory); + p->image_directory = normalize_directory (path); + + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "image_text")), + (p->image_directory ? p->image_directory : "")); + demo_write_init_file (s, p); +} + + +static void +store_text_file (GtkWidget *button, gpointer user_data) +{ + file_selection_data *fsd = (file_selection_data *) user_data; + state *s = fsd->state; + GtkFileSelection *selector = fsd->widget; + GtkWidget *top = s->toplevel_widget; + saver_preferences *p = &s->prefs; + const char *path = gtk_file_selection_get_filename (selector); + + if (p->text_file && !strcmp(p->text_file, path)) + return; /* no change */ + + if (!file_p (path)) + { + char b[255]; + sprintf (b, _("Error:\n\n" "File does not exist: \"%s\"\n"), path); + warning_dialog (GTK_WIDGET (top), b, D_NONE, 100); + return; + } + + if (p->text_file) free (p->text_file); + p->text_file = normalize_directory (path); + + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "text_file_entry")), + (p->text_file ? p->text_file : "")); + demo_write_init_file (s, p); +} + + +static void +store_text_program (GtkWidget *button, gpointer user_data) +{ + file_selection_data *fsd = (file_selection_data *) user_data; + state *s = fsd->state; + GtkFileSelection *selector = fsd->widget; + /*GtkWidget *top = s->toplevel_widget;*/ + saver_preferences *p = &s->prefs; + const char *path = gtk_file_selection_get_filename (selector); + + if (p->text_program && !strcmp(p->text_program, path)) + return; /* no change */ + +# if 0 + if (!file_p (path)) + { + char b[255]; + sprintf (b, _("Error:\n\n" "File does not exist: \"%s\"\n"), path); + warning_dialog (GTK_WIDGET (top), b, D_NONE, 100); + return; + } +# endif + + if (p->text_program) free (p->text_program); + p->text_program = normalize_directory (path); + + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "text_program_entry")), + (p->text_program ? p->text_program : "")); + demo_write_init_file (s, p); +} + + + +static void +browse_image_dir_cancel (GtkWidget *button, gpointer user_data) +{ + file_selection_data *fsd = (file_selection_data *) user_data; + gtk_widget_hide (GTK_WIDGET (fsd->widget)); +} + +static void +browse_image_dir_ok (GtkWidget *button, gpointer user_data) +{ + browse_image_dir_cancel (button, user_data); + store_image_directory (button, user_data); +} + +static void +browse_text_file_ok (GtkWidget *button, gpointer user_data) +{ + browse_image_dir_cancel (button, user_data); + store_text_file (button, user_data); +} + +static void +browse_text_program_ok (GtkWidget *button, gpointer user_data) +{ + browse_image_dir_cancel (button, user_data); + store_text_program (button, user_data); +} + +static void +browse_image_dir_close (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + browse_image_dir_cancel (widget, user_data); +} + + +G_MODULE_EXPORT void +browse_image_dir_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + saver_preferences *p = &s->prefs; + static file_selection_data *fsd = 0; + + GtkFileSelection *selector = GTK_FILE_SELECTION( + gtk_file_selection_new ("Please select the image directory.")); + + if (!fsd) + fsd = (file_selection_data *) malloc (sizeof (*fsd)); + + fsd->widget = selector; + fsd->state = s; + + if (p->image_directory && *p->image_directory) + gtk_file_selection_set_filename (selector, p->image_directory); + + gtk_signal_connect (GTK_OBJECT (selector->ok_button), + "clicked", GTK_SIGNAL_FUNC (browse_image_dir_ok), + (gpointer *) fsd); + gtk_signal_connect (GTK_OBJECT (selector->cancel_button), + "clicked", GTK_SIGNAL_FUNC (browse_image_dir_cancel), + (gpointer *) fsd); + gtk_signal_connect (GTK_OBJECT (selector), "delete_event", + GTK_SIGNAL_FUNC (browse_image_dir_close), + (gpointer *) fsd); + + gtk_widget_set_sensitive (GTK_WIDGET (selector->file_list), False); + + gtk_window_set_modal (GTK_WINDOW (selector), True); + gtk_widget_show (GTK_WIDGET (selector)); +} + + +G_MODULE_EXPORT void +browse_text_file_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + saver_preferences *p = &s->prefs; + static file_selection_data *fsd = 0; + + GtkFileSelection *selector = GTK_FILE_SELECTION( + gtk_file_selection_new ("Please select a text file.")); + + if (!fsd) + fsd = (file_selection_data *) malloc (sizeof (*fsd)); + + fsd->widget = selector; + fsd->state = s; + + if (p->text_file && *p->text_file) + gtk_file_selection_set_filename (selector, p->text_file); + + gtk_signal_connect (GTK_OBJECT (selector->ok_button), + "clicked", GTK_SIGNAL_FUNC (browse_text_file_ok), + (gpointer *) fsd); + gtk_signal_connect (GTK_OBJECT (selector->cancel_button), + "clicked", GTK_SIGNAL_FUNC (browse_image_dir_cancel), + (gpointer *) fsd); + gtk_signal_connect (GTK_OBJECT (selector), "delete_event", + GTK_SIGNAL_FUNC (browse_image_dir_close), + (gpointer *) fsd); + + gtk_window_set_modal (GTK_WINDOW (selector), True); + gtk_widget_show (GTK_WIDGET (selector)); +} + + +G_MODULE_EXPORT void +browse_text_program_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + saver_preferences *p = &s->prefs; + static file_selection_data *fsd = 0; + + GtkFileSelection *selector = GTK_FILE_SELECTION( + gtk_file_selection_new ("Please select a text-generating program.")); + + if (!fsd) + fsd = (file_selection_data *) malloc (sizeof (*fsd)); + + fsd->widget = selector; + fsd->state = s; + + if (p->text_program && *p->text_program) + gtk_file_selection_set_filename (selector, p->text_program); + + gtk_signal_connect (GTK_OBJECT (selector->ok_button), + "clicked", GTK_SIGNAL_FUNC (browse_text_program_ok), + (gpointer *) fsd); + gtk_signal_connect (GTK_OBJECT (selector->cancel_button), + "clicked", GTK_SIGNAL_FUNC (browse_image_dir_cancel), + (gpointer *) fsd); + gtk_signal_connect (GTK_OBJECT (selector), "delete_event", + GTK_SIGNAL_FUNC (browse_image_dir_close), + (gpointer *) fsd); + + gtk_window_set_modal (GTK_WINDOW (selector), True); + gtk_widget_show (GTK_WIDGET (selector)); +} + + + + + +G_MODULE_EXPORT void +settings_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + int list_elt = selected_list_element (s); + + populate_demo_window (s, list_elt); /* reset the widget */ + populate_popup_window (s); /* create UI on popup window */ + gtk_widget_show (s->popup_widget); +} + +static void +settings_sync_cmd_text (state *s) +{ +# ifdef HAVE_XML + GtkWidget *cmd = GTK_WIDGET (name_to_widget (s, "cmd_text")); + char *cmd_line = get_configurator_command_line (s->cdata, False); + gtk_entry_set_text (GTK_ENTRY (cmd), cmd_line); + gtk_entry_set_position (GTK_ENTRY (cmd), strlen (cmd_line)); + free (cmd_line); +# endif /* HAVE_XML */ +} + +G_MODULE_EXPORT void +settings_adv_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + GtkNotebook *notebook = + GTK_NOTEBOOK (name_to_widget (s, "opt_notebook")); + + settings_sync_cmd_text (s); + gtk_notebook_set_page (notebook, 1); +} + +G_MODULE_EXPORT void +settings_std_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + GtkNotebook *notebook = + GTK_NOTEBOOK (name_to_widget (s, "opt_notebook")); + + /* Re-create UI to reflect the in-progress command-line settings. */ + populate_popup_window (s); + + gtk_notebook_set_page (notebook, 0); +} + +G_MODULE_EXPORT void +settings_reset_cb (GtkButton *button, gpointer user_data) +{ +# ifdef HAVE_XML + state *s = global_state_kludge; /* I hate C so much... */ + GtkWidget *cmd = GTK_WIDGET (name_to_widget (s, "cmd_text")); + char *cmd_line = get_configurator_command_line (s->cdata, True); + gtk_entry_set_text (GTK_ENTRY (cmd), cmd_line); + gtk_entry_set_position (GTK_ENTRY (cmd), strlen (cmd_line)); + free (cmd_line); + populate_popup_window (s); +# endif /* HAVE_XML */ +} + +G_MODULE_EXPORT void +settings_switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page, + gint page_num, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + GtkWidget *adv = name_to_widget (s, "adv_button"); + GtkWidget *std = name_to_widget (s, "std_button"); + + if (page_num == 0) + { + gtk_widget_show (adv); + gtk_widget_hide (std); + } + else if (page_num == 1) + { + gtk_widget_hide (adv); + gtk_widget_show (std); + } + else + abort(); +} + + + +G_MODULE_EXPORT void +settings_cancel_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + gtk_widget_hide (s->popup_widget); +} + +G_MODULE_EXPORT void +settings_ok_cb (GtkButton *button, gpointer user_data) +{ + state *s = global_state_kludge; /* I hate C so much... */ + GtkNotebook *notebook = GTK_NOTEBOOK (name_to_widget (s, "opt_notebook")); + int page = gtk_notebook_get_current_page (notebook); + + if (page == 0) + /* Regenerate the command-line from the widget contents before saving. + But don't do this if we're looking at the command-line page already, + or we will blow away what they typed... */ + settings_sync_cmd_text (s); + + flush_popup_changes_and_save (s); + gtk_widget_hide (s->popup_widget); +} + +static gboolean +wm_popup_close_cb (GtkWidget *widget, GdkEvent *event, gpointer data) +{ + state *s = (state *) data; + settings_cancel_cb (0, (gpointer) s); + return TRUE; +} + + + +/* Populating the various widgets + */ + + +/* Returns the number of the last hack run by the server. + */ +static int +server_current_hack (void) +{ + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *dataP = 0; + Display *dpy = GDK_DISPLAY(); + int hack_number = -1; + + if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */ + XA_SCREENSAVER_STATUS, + 0, 3, False, XA_INTEGER, + &type, &format, &nitems, &bytesafter, + &dataP) + == Success + && type == XA_INTEGER + && nitems >= 3 + && dataP) + { + PROP32 *data = (PROP32 *) dataP; + hack_number = (int) data[2] - 1; + } + + if (dataP) XFree (dataP); + + return hack_number; +} + + +/* Finds the number of the last hack that was run, and makes that item be + selected by default. + */ +static void +scroll_to_current_hack (state *s) +{ + saver_preferences *p = &s->prefs; + int hack_number = -1; + + if (p->mode == ONE_HACK) /* in "one" mode, use the one */ + hack_number = p->selected_hack; + if (hack_number < 0) /* otherwise, use the last-run */ + hack_number = server_current_hack (); + if (hack_number < 0) /* failing that, last "one mode" */ + hack_number = p->selected_hack; + if (hack_number < 0) /* failing that, newest hack. */ + { + /* We should only get here if the user does not have a .xscreensaver + file, and the screen has not been blanked with a hack since X + started up: in other words, this is probably a fresh install. + + Instead of just defaulting to hack #0 (in either "programs" or + "alphabetical" order) let's try to default to the last runnable + hack in the "programs" list: this is probably the hack that was + most recently added to the xscreensaver distribution (and so + it's probably the currently-coolest one!) + */ + hack_number = p->screenhacks_count-1; + while (hack_number > 0 && + ! (s->hacks_available_p[hack_number] && + p->screenhacks[hack_number]->enabled_p)) + hack_number--; + } + + if (hack_number >= 0 && hack_number < p->screenhacks_count) + { + int list_elt = s->hack_number_to_list_elt[hack_number]; + GtkWidget *list = name_to_widget (s, "list"); + force_list_select_item (s, list, list_elt, True); + populate_demo_window (s, list_elt); + } +} + + +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")); + GtkListStore *model; + GtkTreeSelection *selection; + GtkCellRenderer *ren; + GtkTreeIter iter; + int i; + + g_object_get (G_OBJECT (list), + "model", &model, + NULL); + if (!model) + { + model = gtk_list_store_new (COL_LAST, G_TYPE_BOOLEAN, G_TYPE_STRING); + g_object_set (G_OBJECT (list), "model", model, NULL); + g_object_unref (model); + + ren = gtk_cell_renderer_toggle_new (); + gtk_tree_view_insert_column_with_attributes (list, COL_ENABLED, + _("Use"), ren, + "active", COL_ENABLED, + NULL); + + g_signal_connect (ren, "toggled", + G_CALLBACK (list_checkbox_cb), + s); + + ren = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (list, COL_NAME, + _("Screen Saver"), ren, + "markup", COL_NAME, + NULL); + + g_signal_connect_after (list, "row_activated", + G_CALLBACK (list_activated_cb), + s); + + selection = gtk_tree_view_get_selection (list); + g_signal_connect (selection, "changed", + G_CALLBACK (list_select_changed_cb), + s); + + } + + for (i = 0; i < s->list_count; i++) + { + int hack_number = s->list_elt_to_hack_number[i]; + screenhack *hack = (hack_number < 0 ? 0 : p->screenhacks[hack_number]); + char *pretty_name; + Bool available_p = (hack && s->hacks_available_p [hack_number]); + + if (!hack) continue; + + /* If we're to suppress uninstalled hacks, check $PATH now. */ + if (p->ignore_uninstalled_p && !available_p) + continue; + + pretty_name = (hack->name + ? strdup (hack->name) + : make_hack_name (dpy, hack->command)); + + if (!available_p) + { + /* Make the text foreground be the color of insensitive widgets + (but don't actually make it be insensitive, since we still + want to be able to click on it.) + */ + GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (list)); + GdkColor *fg = &style->fg[GTK_STATE_INSENSITIVE]; + /* GdkColor *bg = &style->bg[GTK_STATE_INSENSITIVE]; */ + char *buf = (char *) malloc (strlen (pretty_name) + 100); + + sprintf (buf, "%s", + fg->red >> 8, fg->green >> 8, fg->blue >> 8, + /* bg->red >> 8, bg->green >> 8, bg->blue >> 8, */ + pretty_name); + free (pretty_name); + pretty_name = buf; + } + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + COL_ENABLED, hack->enabled_p, + COL_NAME, pretty_name, + -1); + free (pretty_name); + } + +#else /* !HAVE_GTK2 */ + + saver_preferences *p = &s->prefs; + GtkList *list = GTK_LIST (name_to_widget (s, "list")); + int i; + for (i = 0; i < s->list_count; i++) + { + int hack_number = s->list_elt_to_hack_number[i]; + screenhack *hack = (hack_number < 0 ? 0 : p->screenhacks[hack_number]); + + /* A GtkList must contain only GtkListItems, but those can contain + an arbitrary widget. We add an Hbox, and inside that, a Checkbox + and a Label. We handle single and double click events on the + line itself, for clicking on the text, but the interior checkbox + also handles its own events. + */ + GtkWidget *line; + GtkWidget *line_hbox; + GtkWidget *line_check; + GtkWidget *line_label; + char *pretty_name; + Bool available_p = (hack && s->hacks_available_p [hack_number]); + + if (!hack) continue; + + /* If we're to suppress uninstalled hacks, check $PATH now. */ + if (p->ignore_uninstalled_p && !available_p) + continue; + + pretty_name = (hack->name + ? strdup (hack->name) + : make_hack_name (hack->command)); + + line = gtk_list_item_new (); + line_hbox = gtk_hbox_new (FALSE, 0); + line_check = gtk_check_button_new (); + line_label = gtk_label_new (pretty_name); + + gtk_container_add (GTK_CONTAINER (line), line_hbox); + gtk_box_pack_start (GTK_BOX (line_hbox), line_check, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (line_hbox), line_label, FALSE, FALSE, 0); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (line_check), + hack->enabled_p); + gtk_label_set_justify (GTK_LABEL (line_label), GTK_JUSTIFY_LEFT); + + gtk_widget_show (line_check); + gtk_widget_show (line_label); + gtk_widget_show (line_hbox); + gtk_widget_show (line); + + free (pretty_name); + + gtk_container_add (GTK_CONTAINER (list), line); + gtk_signal_connect (GTK_OBJECT (line), "button_press_event", + GTK_SIGNAL_FUNC (list_doubleclick_cb), + (gpointer) s); + + gtk_signal_connect (GTK_OBJECT (line_check), "toggled", + GTK_SIGNAL_FUNC (list_checkbox_cb), + (gpointer) s); + + gtk_widget_show (line); + + if (!available_p) + { + /* Make the widget be colored like insensitive widgets + (but don't actually make it be insensitive, since we + still want to be able to click on it.) + */ + GtkRcStyle *rc_style; + GdkColor fg, bg; + + gtk_widget_realize (GTK_WIDGET (line_label)); + + fg = GTK_WIDGET (line_label)->style->fg[GTK_STATE_INSENSITIVE]; + bg = GTK_WIDGET (line_label)->style->bg[GTK_STATE_INSENSITIVE]; + + rc_style = gtk_rc_style_new (); + rc_style->fg[GTK_STATE_NORMAL] = fg; + rc_style->bg[GTK_STATE_NORMAL] = bg; + rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG|GTK_RC_BG; + + gtk_widget_modify_style (GTK_WIDGET (line_label), rc_style); + gtk_rc_style_unref (rc_style); + } + } + + gtk_signal_connect (GTK_OBJECT (list), "select_child", + GTK_SIGNAL_FUNC (list_select_cb), + (gpointer) s); + gtk_signal_connect (GTK_OBJECT (list), "unselect_child", + GTK_SIGNAL_FUNC (list_unselect_cb), + (gpointer) s); +#endif /* !HAVE_GTK2 */ +} + +static void +update_list_sensitivity (state *s) +{ + saver_preferences *p = &s->prefs; + Bool sensitive = (p->mode == RANDOM_HACKS || + p->mode == RANDOM_HACKS_SAME || + p->mode == ONE_HACK); + Bool checkable = (p->mode == RANDOM_HACKS || + p->mode == RANDOM_HACKS_SAME); + Bool blankable = (p->mode != DONT_BLANK); + +#ifndef HAVE_GTK2 + GtkWidget *head = name_to_widget (s, "col_head_hbox"); + GtkWidget *use = name_to_widget (s, "use_col_frame"); +#endif /* HAVE_GTK2 */ + GtkWidget *scroller = name_to_widget (s, "scroller"); + GtkWidget *buttons = name_to_widget (s, "next_prev_hbox"); + GtkWidget *blanker = name_to_widget (s, "blanking_table"); + +#ifdef HAVE_GTK2 + GtkTreeView *list = GTK_TREE_VIEW (name_to_widget (s, "list")); + GtkTreeViewColumn *use = gtk_tree_view_get_column (list, COL_ENABLED); +#else /* !HAVE_GTK2 */ + GtkList *list = GTK_LIST (name_to_widget (s, "list")); + GList *kids = gtk_container_children (GTK_CONTAINER (list)); + + gtk_widget_set_sensitive (GTK_WIDGET (head), sensitive); +#endif /* !HAVE_GTK2 */ + gtk_widget_set_sensitive (GTK_WIDGET (scroller), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (buttons), sensitive); + + gtk_widget_set_sensitive (GTK_WIDGET (blanker), blankable); + +#ifdef HAVE_GTK2 + gtk_tree_view_column_set_visible (use, checkable); +#else /* !HAVE_GTK2 */ + if (checkable) + gtk_widget_show (use); /* the "Use" column header */ + else + gtk_widget_hide (use); + + while (kids) + { + GtkBin *line = GTK_BIN (kids->data); + GtkContainer *line_hbox = GTK_CONTAINER (line->child); + GtkWidget *line_check = + GTK_WIDGET (gtk_container_children (line_hbox)->data); + + if (checkable) + gtk_widget_show (line_check); + else + gtk_widget_hide (line_check); + + kids = kids->next; + } +#endif /* !HAVE_GTK2 */ +} + + +static void +populate_prefs_page (state *s) +{ + saver_preferences *p = &s->prefs; + + Bool can_lock_p = True; + + /* Disable all the "lock" controls if locking support was not provided + at compile-time, or if running on MacOS. */ +# if defined(NO_LOCKING) || defined(__APPLE__) + can_lock_p = False; +# endif + + + /* If there is only one screen, the mode menu contains + "random" but not "random-same". + */ + if (s->nscreens <= 1 && p->mode == RANDOM_HACKS_SAME) + p->mode = RANDOM_HACKS; + + + /* The file supports timeouts of less than a minute, but the GUI does + not, so throttle the values to be at least one minute (since "0" is + a bad rounding choice...) + */ +# define THROTTLE(NAME) if (p->NAME != 0 && p->NAME < 60000) p->NAME = 60000 + THROTTLE (timeout); + THROTTLE (cycle); + /* THROTTLE (passwd_timeout); */ /* GUI doesn't set this; leave it alone */ +# undef THROTTLE + +# define FMT_MINUTES(NAME,N) \ + gtk_spin_button_set_value (GTK_SPIN_BUTTON (name_to_widget (s, (NAME))), (double)((N) + 59) / (60 * 1000)) + +# define FMT_SECONDS(NAME,N) \ + gtk_spin_button_set_value (GTK_SPIN_BUTTON (name_to_widget (s, (NAME))), (double)((N) / 1000)) + + FMT_MINUTES ("timeout_spinbutton", p->timeout); + FMT_MINUTES ("cycle_spinbutton", p->cycle); + FMT_MINUTES ("lock_spinbutton", p->lock_timeout); + FMT_MINUTES ("dpms_standby_spinbutton", p->dpms_standby); + FMT_MINUTES ("dpms_suspend_spinbutton", p->dpms_suspend); + FMT_MINUTES ("dpms_off_spinbutton", p->dpms_off); + FMT_SECONDS ("fade_spinbutton", p->fade_seconds); + +# undef FMT_MINUTES +# undef FMT_SECONDS + +# define TOGGLE_ACTIVE(NAME,ACTIVEP) \ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (name_to_widget (s,(NAME))),\ + (ACTIVEP)) + + TOGGLE_ACTIVE ("lock_button", p->lock_p); +#if 0 + TOGGLE_ACTIVE ("verbose_button", p->verbose_p); + TOGGLE_ACTIVE ("capture_button", p->capture_stderr_p); + TOGGLE_ACTIVE ("splash_button", p->splash_p); +#endif + TOGGLE_ACTIVE ("dpms_button", p->dpms_enabled_p); + TOGGLE_ACTIVE ("dpms_quickoff_button", p->dpms_quickoff_p); + TOGGLE_ACTIVE ("grab_desk_button", p->grab_desktop_p); + TOGGLE_ACTIVE ("grab_video_button", p->grab_video_p); + TOGGLE_ACTIVE ("grab_image_button", p->random_image_p); + TOGGLE_ACTIVE ("install_button", p->install_cmap_p); + TOGGLE_ACTIVE ("fade_button", p->fade_p); + TOGGLE_ACTIVE ("unfade_button", p->unfade_p); + + switch (p->tmode) + { + case TEXT_LITERAL: TOGGLE_ACTIVE ("text_radio", True); break; + case TEXT_FILE: TOGGLE_ACTIVE ("text_file_radio", True); break; + case TEXT_PROGRAM: TOGGLE_ACTIVE ("text_program_radio", True); break; + case TEXT_URL: TOGGLE_ACTIVE ("text_url_radio", True); break; + default: TOGGLE_ACTIVE ("text_host_radio", True); break; + } + +# undef TOGGLE_ACTIVE + + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "image_text")), + (p->image_directory ? p->image_directory : "")); + gtk_widget_set_sensitive (name_to_widget (s, "image_text"), + p->random_image_p); + gtk_widget_set_sensitive (name_to_widget (s, "image_browse_button"), + p->random_image_p); + + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "text_entry")), + (p->text_literal ? p->text_literal : "")); + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "text_file_entry")), + (p->text_file ? p->text_file : "")); + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "text_program_entry")), + (p->text_program ? p->text_program : "")); + gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, "text_url_entry")), + (p->text_url ? p->text_url : "")); + + gtk_widget_set_sensitive (name_to_widget (s, "text_entry"), + p->tmode == TEXT_LITERAL); + gtk_widget_set_sensitive (name_to_widget (s, "text_file_entry"), + p->tmode == TEXT_FILE); + gtk_widget_set_sensitive (name_to_widget (s, "text_file_browse"), + p->tmode == TEXT_FILE); + gtk_widget_set_sensitive (name_to_widget (s, "text_program_entry"), + p->tmode == TEXT_PROGRAM); + gtk_widget_set_sensitive (name_to_widget (s, "text_program_browse"), + p->tmode == TEXT_PROGRAM); + gtk_widget_set_sensitive (name_to_widget (s, "text_url_entry"), + p->tmode == TEXT_URL); + + + /* Map the `saver_mode' enum to mode menu to values. */ + { + GtkOptionMenu *opt = GTK_OPTION_MENU (name_to_widget (s, "mode_menu")); + + int i; + for (i = 0; i < countof(mode_menu_order); i++) + if (mode_menu_order[i] == p->mode) + break; + gtk_option_menu_set_history (opt, i); + update_list_sensitivity (s); + } + + { + Bool found_any_writable_cells = False; + Bool fading_possible = False; + Bool dpms_supported = False; + + Display *dpy = GDK_DISPLAY(); + int nscreens = ScreenCount(dpy); /* real screens, not Xinerama */ + int i; + for (i = 0; i < nscreens; i++) + { + Screen *s = ScreenOfDisplay (dpy, i); + if (has_writable_cells (s, DefaultVisualOfScreen (s))) + { + found_any_writable_cells = True; + break; + } + } + + fading_possible = found_any_writable_cells; +#ifdef HAVE_XF86VMODE_GAMMA + fading_possible = True; +#endif + +#ifdef HAVE_DPMS_EXTENSION + { + int op = 0, event = 0, error = 0; + if (XQueryExtension (dpy, "DPMS", &op, &event, &error)) + dpms_supported = True; + } +#endif /* HAVE_DPMS_EXTENSION */ + + +# define SENSITIZE(NAME,SENSITIVEP) \ + gtk_widget_set_sensitive (name_to_widget (s, (NAME)), (SENSITIVEP)) + + /* Blanking and Locking + */ + SENSITIZE ("lock_button", can_lock_p); + SENSITIZE ("lock_spinbutton", can_lock_p && p->lock_p); + SENSITIZE ("lock_mlabel", can_lock_p && p->lock_p); + + /* DPMS + */ +dpms_supported=1; + SENSITIZE ("dpms_frame", dpms_supported); + SENSITIZE ("dpms_button", dpms_supported); + SENSITIZE ("dpms_quickoff_button", dpms_supported); + + SENSITIZE ("dpms_standby_label", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_standby_mlabel", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_standby_spinbutton", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_suspend_label", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_suspend_mlabel", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_suspend_spinbutton", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_off_label", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_off_mlabel", dpms_supported && p->dpms_enabled_p); + SENSITIZE ("dpms_off_spinbutton", dpms_supported && p->dpms_enabled_p); + + /* Colormaps + */ + SENSITIZE ("cmap_frame", found_any_writable_cells || fading_possible); + SENSITIZE ("install_button", found_any_writable_cells); + SENSITIZE ("fade_button", fading_possible); + SENSITIZE ("unfade_button", fading_possible); + + SENSITIZE ("fade_label", (fading_possible && + (p->fade_p || p->unfade_p))); + SENSITIZE ("fade_spinbutton", (fading_possible && + (p->fade_p || p->unfade_p))); + +# undef SENSITIZE + } +} + + +static void +populate_popup_window (state *s) +{ + GtkLabel *doc = GTK_LABEL (name_to_widget (s, "doc")); + char *doc_string = 0; + + /* #### not in Gtk 1.2 + gtk_label_set_selectable (doc); + */ + +# ifdef HAVE_XML + if (s->cdata) + { + free_conf_data (s->cdata); + s->cdata = 0; + } + + { + saver_preferences *p = &s->prefs; + int list_elt = selected_list_element (s); + int hack_number = (list_elt >= 0 && list_elt < s->list_count + ? s->list_elt_to_hack_number[list_elt] + : -1); + screenhack *hack = (hack_number >= 0 ? p->screenhacks[hack_number] : 0); + if (hack) + { + GtkWidget *parent = name_to_widget (s, "settings_vbox"); + GtkWidget *cmd = GTK_WIDGET (name_to_widget (s, "cmd_text")); + const char *cmd_line = gtk_entry_get_text (GTK_ENTRY (cmd)); + s->cdata = load_configurator (cmd_line, s->debug_p); + if (s->cdata && s->cdata->widget) + gtk_box_pack_start (GTK_BOX (parent), s->cdata->widget, + TRUE, TRUE, 0); + } + } + + doc_string = (s->cdata + ? s->cdata->description + : 0); +# else /* !HAVE_XML */ + doc_string = _("Descriptions not available: no XML support compiled in."); +# endif /* !HAVE_XML */ + + gtk_label_set_text (doc, (doc_string + ? _(doc_string) + : _("No description available."))); +} + + +static void +sensitize_demo_widgets (state *s, Bool sensitive_p) +{ + const char *names[] = { "demo", "settings", + "cmd_label", "cmd_text", "manual", + "visual", "visual_combo" }; + int i; + for (i = 0; i < countof(names); i++) + { + GtkWidget *w = name_to_widget (s, names[i]); + gtk_widget_set_sensitive (GTK_WIDGET(w), sensitive_p); + } +} + + +static void +sensitize_menu_items (state *s, Bool force_p) +{ + static Bool running_p = False; + static time_t last_checked = 0; + time_t now = time ((time_t *) 0); + const char *names[] = { "activate_menu", "lock_menu", "kill_menu", + /* "demo" */ }; + int i; + + if (force_p || now > last_checked + 10) /* check every 10 seconds */ + { + running_p = xscreensaver_running_p (s); + last_checked = time ((time_t *) 0); + } + + for (i = 0; i < countof(names); i++) + { + GtkWidget *w = name_to_widget (s, names[i]); + gtk_widget_set_sensitive (GTK_WIDGET(w), running_p); + } +} + + +/* When the File menu is de-posted after a "Restart Daemon" command, + the window underneath doesn't repaint for some reason. I guess this + is a bug in exposure handling in GTK or GDK. This works around it. + */ +static void +force_dialog_repaint (state *s) +{ +#if 1 + /* Tell GDK to invalidate and repaint the whole window. + */ + GdkWindow *w = GET_WINDOW (s->toplevel_widget); + GdkRegion *region = gdk_region_new (); + GdkRectangle rect; + rect.x = rect.y = 0; + rect.width = rect.height = 32767; + gdk_region_union_with_rect (region, &rect); + gdk_window_invalidate_region (w, region, True); + gdk_region_destroy (region); + gdk_window_process_updates (w, True); +#else + /* Force the server to send an exposure event by creating and then + destroying a window as a child of the top level shell. + */ + Display *dpy = GDK_DISPLAY(); + Window parent = GDK_WINDOW_XWINDOW (s->toplevel_widget->window); + Window w; + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, parent, &xgwa); + w = XCreateSimpleWindow (dpy, parent, 0, 0, xgwa.width, xgwa.height, 0,0,0); + XMapRaised (dpy, w); + XDestroyWindow (dpy, w); + XSync (dpy, False); +#endif +} + + +/* Even though we've given these text fields a maximum number of characters, + their default size is still about 30 characters wide -- so measure out + a string in their font, and resize them to just fit that. + */ +static void +fix_text_entry_sizes (state *s) +{ + GtkWidget *w; + +# if 0 /* appears no longer necessary with Gtk 1.2.10 */ + const char * const spinbuttons[] = { + "timeout_spinbutton", "cycle_spinbutton", "lock_spinbutton", + "dpms_standby_spinbutton", "dpms_suspend_spinbutton", + "dpms_off_spinbutton", + "-fade_spinbutton" }; + int i; + int width = 0; + + for (i = 0; i < countof(spinbuttons); i++) + { + const char *n = spinbuttons[i]; + int cols = 4; + while (*n == '-') n++, cols--; + w = GTK_WIDGET (name_to_widget (s, n)); + width = gdk_text_width (w->style->font, "MMMMMMMM", cols); + gtk_widget_set_usize (w, width, -2); + } + + /* Now fix the width of the combo box. + */ + w = GTK_WIDGET (name_to_widget (s, "visual_combo")); + w = GTK_COMBO (w)->entry; + width = gdk_string_width (w->style->font, "PseudoColor___"); + gtk_widget_set_usize (w, width, -2); + + /* Now fix the width of the file entry text. + */ + w = GTK_WIDGET (name_to_widget (s, "image_text")); + width = gdk_string_width (w->style->font, "mmmmmmmmmmmmmm"); + gtk_widget_set_usize (w, width, -2); + + /* Now fix the width of the command line text. + */ + w = GTK_WIDGET (name_to_widget (s, "cmd_text")); + width = gdk_string_width (w->style->font, "mmmmmmmmmmmmmmmmmmmm"); + gtk_widget_set_usize (w, width, -2); + +# endif /* 0 */ + + /* Now fix the height of the list widget: + make it default to being around 10 text-lines high instead of 4. + */ + w = GTK_WIDGET (name_to_widget (s, "list")); + { + int lines = 10; + int height; + int leading = 3; /* approximate is ok... */ + int border = 2; + +#ifdef HAVE_GTK2 + PangoFontMetrics *pain = + pango_context_get_metrics (gtk_widget_get_pango_context (w), + gtk_widget_get_style (w)->font_desc, + gtk_get_default_language ()); + height = PANGO_PIXELS (pango_font_metrics_get_ascent (pain) + + pango_font_metrics_get_descent (pain)); +#else /* !HAVE_GTK2 */ + height = w->style->font->ascent + w->style->font->descent; +#endif /* !HAVE_GTK2 */ + + height += leading; + height *= lines; + height += border * 2; + w = GTK_WIDGET (name_to_widget (s, "scroller")); + gtk_widget_set_usize (w, -2, height); + } +} + + +#ifndef HAVE_GTK2 + +/* Pixmaps for the up and down arrow buttons (yeah, this is sleazy...) + */ + +static char *up_arrow_xpm[] = { + "15 15 4 1", + " c None", + "- c #FFFFFF", + "+ c #D6D6D6", + "@ c #000000", + + " @ ", + " @ ", + " -+@ ", + " -+@ ", + " -+++@ ", + " -+++@ ", + " -+++++@ ", + " -+++++@ ", + " -+++++++@ ", + " -+++++++@ ", + " -+++++++++@ ", + " -+++++++++@ ", + " -+++++++++++@ ", + " @@@@@@@@@@@@@ ", + " ", + + /* Need these here because gdk_pixmap_create_from_xpm_d() walks off + the end of the array (Gtk 1.2.5.) */ + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" +}; + +static char *down_arrow_xpm[] = { + "15 15 4 1", + " c None", + "- c #FFFFFF", + "+ c #D6D6D6", + "@ c #000000", + + " ", + " ------------- ", + " -+++++++++++@ ", + " -+++++++++@ ", + " -+++++++++@ ", + " -+++++++@ ", + " -+++++++@ ", + " -+++++@ ", + " -+++++@ ", + " -+++@ ", + " -+++@ ", + " -+@ ", + " -+@ ", + " @ ", + " @ ", + + /* Need these here because gdk_pixmap_create_from_xpm_d() walks off + the end of the array (Gtk 1.2.5.) */ + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" +}; + +static void +pixmapify_button (state *s, int down_p) +{ + GdkPixmap *pixmap; + GdkBitmap *mask; + GtkWidget *pixmapwid; + GtkStyle *style; + GtkWidget *w; + + w = GTK_WIDGET (name_to_widget (s, (down_p ? "next" : "prev"))); + style = gtk_widget_get_style (w); + mask = 0; + pixmap = gdk_pixmap_create_from_xpm_d (w->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (down_p + ? (gchar **) down_arrow_xpm + : (gchar **) up_arrow_xpm)); + pixmapwid = gtk_pixmap_new (pixmap, mask); + gtk_widget_show (pixmapwid); + gtk_container_remove (GTK_CONTAINER (w), GTK_BIN (w)->child); + gtk_container_add (GTK_CONTAINER (w), pixmapwid); +} + +static void +map_next_button_cb (GtkWidget *w, gpointer user_data) +{ + state *s = (state *) user_data; + pixmapify_button (s, 1); +} + +static void +map_prev_button_cb (GtkWidget *w, gpointer user_data) +{ + state *s = (state *) user_data; + pixmapify_button (s, 0); +} +#endif /* !HAVE_GTK2 */ + + +#ifndef HAVE_GTK2 +/* Work around a Gtk bug that causes label widgets to wrap text too early. + */ + +static void +you_are_not_a_unique_or_beautiful_snowflake (GtkWidget *label, + GtkAllocation *allocation, + void *foo) +{ + GtkRequisition req; + GtkWidgetAuxInfo *aux_info; + + aux_info = gtk_object_get_data (GTK_OBJECT (label), "gtk-aux-info"); + + aux_info->width = allocation->width; + aux_info->height = -2; + aux_info->x = -1; + aux_info->y = -1; + + gtk_widget_size_request (label, &req); +} + +/* Feel the love. Thanks to Nat Friedman for finding this workaround. + */ +static void +eschew_gtk_lossage (GtkLabel *label) +{ + GtkWidgetAuxInfo *aux_info = g_new0 (GtkWidgetAuxInfo, 1); + aux_info->width = GTK_WIDGET (label)->allocation.width; + aux_info->height = -2; + aux_info->x = -1; + aux_info->y = -1; + + gtk_object_set_data (GTK_OBJECT (label), "gtk-aux-info", aux_info); + + gtk_signal_connect (GTK_OBJECT (label), "size_allocate", + GTK_SIGNAL_FUNC (you_are_not_a_unique_or_beautiful_snowflake), + 0); + + gtk_widget_set_usize (GTK_WIDGET (label), -2, -2); + + gtk_widget_queue_resize (GTK_WIDGET (label)); +} +#endif /* !HAVE_GTK2 */ + + +static void +populate_demo_window (state *s, int list_elt) +{ + Display *dpy = GDK_DISPLAY(); + saver_preferences *p = &s->prefs; + screenhack *hack; + char *pretty_name; + GtkFrame *frame1 = GTK_FRAME (name_to_widget (s, "preview_frame")); + GtkFrame *frame2 = GTK_FRAME (name_to_widget (s, "opt_frame")); + GtkEntry *cmd = GTK_ENTRY (name_to_widget (s, "cmd_text")); + GtkCombo *vis = GTK_COMBO (name_to_widget (s, "visual_combo")); + GtkWidget *list = GTK_WIDGET (name_to_widget (s, "list")); + + if (p->mode == BLANK_ONLY) + { + hack = 0; + pretty_name = strdup (_("Blank Screen")); + schedule_preview (s, 0); + } + else if (p->mode == DONT_BLANK) + { + hack = 0; + pretty_name = strdup (_("Screen Saver Disabled")); + schedule_preview (s, 0); + } + else + { + int hack_number = (list_elt >= 0 && list_elt < s->list_count + ? s->list_elt_to_hack_number[list_elt] + : -1); + hack = (hack_number >= 0 ? p->screenhacks[hack_number] : 0); + + pretty_name = (hack + ? (hack->name + ? strdup (hack->name) + : make_hack_name (dpy, hack->command)) + : 0); + + if (hack) + schedule_preview (s, hack->command); + else + schedule_preview (s, 0); + } + + if (!pretty_name) + pretty_name = strdup (_("Preview")); + + gtk_frame_set_label (frame1, _(pretty_name)); + gtk_frame_set_label (frame2, _(pretty_name)); + + gtk_entry_set_text (cmd, (hack ? hack->command : "")); + gtk_entry_set_position (cmd, 0); + + { + char title[255]; + sprintf (title, _("%s: %.100s Settings"), + progclass, (pretty_name ? pretty_name : "???")); + gtk_window_set_title (GTK_WINDOW (s->popup_widget), title); + } + + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry), + (hack + ? (hack->visual && *hack->visual + ? hack->visual + : _("Any")) + : "")); + + sensitize_demo_widgets (s, (hack ? True : False)); + + if (pretty_name) free (pretty_name); + + ensure_selected_item_visible (list); + + s->_selected_list_element = list_elt; +} + + +static void +widget_deleter (GtkWidget *widget, gpointer data) +{ + /* #### Well, I want to destroy these widgets, but if I do that, they get + referenced again, and eventually I get a SEGV. So instead of + destroying them, I'll just hide them, and leak a bunch of memory + every time the disk file changes. Go go go Gtk! + + #### Ok, that's a lie, I get a crash even if I just hide the widget + and don't ever delete it. Fuck! + */ +#if 0 + gtk_widget_destroy (widget); +#else + gtk_widget_hide (widget); +#endif +} + + +static char **sort_hack_cmp_names_kludge; +static int +sort_hack_cmp (const void *a, const void *b) +{ + if (a == b) + return 0; + else + { + int aa = *(int *) a; + int bb = *(int *) b; + const char last[] = "\377\377\377\377\377\377\377\377\377\377\377"; + return strcmp ((aa < 0 ? last : sort_hack_cmp_names_kludge[aa]), + (bb < 0 ? last : sort_hack_cmp_names_kludge[bb])); + } +} + + +static void +initialize_sort_map (state *s) +{ + Display *dpy = GDK_DISPLAY(); + saver_preferences *p = &s->prefs; + int i, j; + + if (s->list_elt_to_hack_number) free (s->list_elt_to_hack_number); + if (s->hack_number_to_list_elt) free (s->hack_number_to_list_elt); + if (s->hacks_available_p) free (s->hacks_available_p); + + s->list_elt_to_hack_number = (int *) + calloc (sizeof(int), p->screenhacks_count + 1); + s->hack_number_to_list_elt = (int *) + calloc (sizeof(int), p->screenhacks_count + 1); + s->hacks_available_p = (Bool *) + calloc (sizeof(Bool), p->screenhacks_count + 1); + s->total_available = 0; + + /* Check which hacks actually exist on $PATH + */ + for (i = 0; i < p->screenhacks_count; i++) + { + screenhack *hack = p->screenhacks[i]; + int on = on_path_p (hack->command) ? 1 : 0; + s->hacks_available_p[i] = on; + s->total_available += on; + } + + /* Initialize list->hack table to unsorted mapping, omitting nonexistent + hacks, if desired. + */ + j = 0; + for (i = 0; i < p->screenhacks_count; i++) + { + if (!p->ignore_uninstalled_p || + s->hacks_available_p[i]) + s->list_elt_to_hack_number[j++] = i; + } + s->list_count = j; + + for (; j < p->screenhacks_count; j++) + s->list_elt_to_hack_number[j] = -1; + + + /* Generate list of sortable names (once) + */ + sort_hack_cmp_names_kludge = (char **) + calloc (sizeof(char *), p->screenhacks_count); + for (i = 0; i < p->screenhacks_count; i++) + { + screenhack *hack = p->screenhacks[i]; + char *name = (hack->name && *hack->name + ? strdup (hack->name) + : make_hack_name (dpy, hack->command)); + char *str; + for (str = name; *str; str++) + *str = tolower(*str); + sort_hack_cmp_names_kludge[i] = name; + } + + /* Sort list->hack map alphabetically + */ + qsort (s->list_elt_to_hack_number, + p->screenhacks_count, + sizeof(*s->list_elt_to_hack_number), + sort_hack_cmp); + + /* Free names + */ + for (i = 0; i < p->screenhacks_count; i++) + free (sort_hack_cmp_names_kludge[i]); + free (sort_hack_cmp_names_kludge); + sort_hack_cmp_names_kludge = 0; + + /* Build inverse table */ + for (i = 0; i < p->screenhacks_count; i++) + { + int n = s->list_elt_to_hack_number[i]; + if (n != -1) + s->hack_number_to_list_elt[n] = i; + } +} + + +static int +maybe_reload_init_file (state *s) +{ + Display *dpy = GDK_DISPLAY(); + saver_preferences *p = &s->prefs; + int status = 0; + + static Bool reentrant_lock = False; + if (reentrant_lock) return 0; + reentrant_lock = True; + + if (init_file_changed_p (p)) + { + const char *f = init_file_name(); + char *b; + int list_elt; + GtkWidget *list; + + if (!f || !*f) return 0; + b = (char *) malloc (strlen(f) + 1024); + sprintf (b, + _("Warning:\n\n" + "file \"%s\" has changed, reloading.\n"), + f); + warning_dialog (s->toplevel_widget, b, D_NONE, 100); + free (b); + + load_init_file (dpy, p); + initialize_sort_map (s); + + list_elt = selected_list_element (s); + list = name_to_widget (s, "list"); + gtk_container_foreach (GTK_CONTAINER (list), widget_deleter, NULL); + populate_hack_list (s); + force_list_select_item (s, list, list_elt, True); + populate_prefs_page (s); + populate_demo_window (s, list_elt); + ensure_selected_item_visible (list); + + status = 1; + } + + reentrant_lock = False; + return status; +} + + + +/* Making the preview window have the right X visual (so that GL works.) + */ + +static Visual *get_best_gl_visual (state *); + +static GdkVisual * +x_visual_to_gdk_visual (Visual *xv) +{ + GList *gvs = gdk_list_visuals(); + if (!xv) return gdk_visual_get_system(); + for (; gvs; gvs = gvs->next) + { + GdkVisual *gv = (GdkVisual *) gvs->data; + if (xv == GDK_VISUAL_XVISUAL (gv)) + return gv; + } + fprintf (stderr, "%s: couldn't convert X Visual 0x%lx to a GdkVisual\n", + blurb(), (unsigned long) xv->visualid); + abort(); +} + +static void +clear_preview_window (state *s) +{ + GtkWidget *p; + GdkWindow *window; + GtkStyle *style; + + if (!s->toplevel_widget) return; /* very early */ + p = name_to_widget (s, "preview"); + window = GET_WINDOW (p); + + if (!window) return; + + /* Flush the widget background down into the window, in case a subproc + has changed it. */ + style = gtk_widget_get_style (p); + gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]); + gdk_window_clear (window); + + { + int list_elt = selected_list_element (s); + int hack_number = (list_elt >= 0 + ? s->list_elt_to_hack_number[list_elt] + : -1); + Bool available_p = (hack_number >= 0 + ? s->hacks_available_p [hack_number] + : True); + Bool nothing_p = (s->total_available < 5); + +#ifdef HAVE_GTK2 + GtkWidget *notebook = name_to_widget (s, "preview_notebook"); + gtk_notebook_set_page (GTK_NOTEBOOK (notebook), + (s->running_preview_error_p + ? (available_p ? 1 : + nothing_p ? 3 : 2) + : 0)); +#else /* !HAVE_GTK2 */ + if (s->running_preview_error_p) + { + const char * const lines1[] = { N_("No Preview"), N_("Available") }; + const char * const lines2[] = { N_("Not"), N_("Installed") }; + int nlines = countof(lines1); + int lh = p->style->font->ascent + p->style->font->descent; + int y, i; + gint w, h; + + const char * const *lines = (available_p ? lines1 : lines2); + + gdk_window_get_size (window, &w, &h); + y = (h - (lh * nlines)) / 2; + y += p->style->font->ascent; + for (i = 0; i < nlines; i++) + { + int sw = gdk_string_width (p->style->font, _(lines[i])); + int x = (w - sw) / 2; + gdk_draw_string (window, p->style->font, + p->style->fg_gc[GTK_STATE_NORMAL], + x, y, _(lines[i])); + y += lh; + } + } +#endif /* !HAVE_GTK2 */ + } + + gdk_flush (); +} + + +static void +reset_preview_window (state *s) +{ + /* On some systems (most recently, MacOS X) OpenGL programs get confused + when you kill one and re-start another on the same window. So maybe + it's best to just always destroy and recreate the preview window + when changing hacks, instead of always trying to reuse the same one? + */ + GtkWidget *pr = name_to_widget (s, "preview"); + if (GET_REALIZED (pr)) + { + GdkWindow *window = GET_WINDOW (pr); + Window oid = (window ? GDK_WINDOW_XWINDOW (window) : 0); + Window id; + gtk_widget_hide (pr); + gtk_widget_unrealize (pr); + gtk_widget_realize (pr); + gtk_widget_show (pr); + id = (window ? GDK_WINDOW_XWINDOW (window) : 0); + if (s->debug_p) + fprintf (stderr, "%s: window id 0x%X -> 0x%X\n", blurb(), + (unsigned int) oid, + (unsigned int) id); + } +} + + +static void +fix_preview_visual (state *s) +{ + GtkWidget *widget = name_to_widget (s, "preview"); + Visual *xvisual = get_best_gl_visual (s); + GdkVisual *visual = x_visual_to_gdk_visual (xvisual); + GdkVisual *dvisual = gdk_visual_get_system(); + GdkColormap *cmap = (visual == dvisual + ? gdk_colormap_get_system () + : gdk_colormap_new (visual, False)); + + if (s->debug_p) + fprintf (stderr, "%s: using %s visual 0x%lx\n", blurb(), + (visual == dvisual ? "default" : "non-default"), + (xvisual ? (unsigned long) xvisual->visualid : 0L)); + + if (!GET_REALIZED (widget) || + gtk_widget_get_visual (widget) != visual) + { + gtk_widget_unrealize (widget); + gtk_widget_set_visual (widget, visual); + gtk_widget_set_colormap (widget, cmap); + gtk_widget_realize (widget); + } + + /* Set the Widget colors to be white-on-black. */ + { + GdkWindow *window = GET_WINDOW (widget); + GtkStyle *style = gtk_style_copy (gtk_widget_get_style (widget)); + GdkColormap *cmap = gtk_widget_get_colormap (widget); + GdkColor *fg = &style->fg[GTK_STATE_NORMAL]; + GdkColor *bg = &style->bg[GTK_STATE_NORMAL]; + GdkGC *fgc = gdk_gc_new(window); + GdkGC *bgc = gdk_gc_new(window); + if (!gdk_color_white (cmap, fg)) abort(); + if (!gdk_color_black (cmap, bg)) abort(); + gdk_gc_set_foreground (fgc, fg); + gdk_gc_set_background (fgc, bg); + gdk_gc_set_foreground (bgc, bg); + gdk_gc_set_background (bgc, fg); + style->fg_gc[GTK_STATE_NORMAL] = fgc; + style->bg_gc[GTK_STATE_NORMAL] = fgc; + gtk_widget_set_style (widget, style); + + /* For debugging purposes, put a title on the window (so that + it can be easily found in the output of "xwininfo -tree".) + */ + gdk_window_set_title (window, "Preview"); + } + + gtk_widget_show (widget); +} + + +/* Subprocesses + */ + +static char * +subproc_pretty_name (state *s) +{ + if (s->running_preview_cmd) + { + char *ps = strdup (s->running_preview_cmd); + char *ss = strchr (ps, ' '); + if (ss) *ss = 0; + ss = strrchr (ps, '/'); + if (!ss) + ss = ps; + else + { + ss = strdup (ss+1); + free (ps); + } + return ss; + } + else + return strdup ("???"); +} + + +static void +reap_zombies (state *s) +{ + int wait_status = 0; + pid_t pid; + while ((pid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED)) > 0) + { + if (s->debug_p) + { + if (pid == s->running_preview_pid) + { + char *ss = subproc_pretty_name (s); + fprintf (stderr, "%s: pid %lu (%s) died\n", blurb(), + (unsigned long) pid, ss); + free (ss); + } + else + fprintf (stderr, "%s: pid %lu died\n", blurb(), + (unsigned long) pid); + } + } +} + + +/* Mostly lifted from driver/subprocs.c */ +static Visual * +get_best_gl_visual (state *s) +{ + Display *dpy = GDK_DISPLAY(); + pid_t forked; + int fds [2]; + int in, out; + char buf[1024]; + + char *av[10]; + int ac = 0; + + av[ac++] = "xscreensaver-gl-helper"; + av[ac] = 0; + + if (pipe (fds)) + { + perror ("error creating pipe:"); + return 0; + } + + in = fds [0]; + out = fds [1]; + + switch ((int) (forked = fork ())) + { + case -1: + { + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + exit (1); + } + case 0: + { + int stdout_fd = 1; + + close (in); /* don't need this one */ + close (ConnectionNumber (dpy)); /* close display fd */ + + if (dup2 (out, stdout_fd) < 0) /* pipe stdout */ + { + perror ("could not dup() a new stdout:"); + return 0; + } + + execvp (av[0], av); /* shouldn't return. */ + + if (errno != ENOENT) + { + /* Ignore "no such file or directory" errors, unless verbose. + Issue all other exec errors, though. */ + sprintf (buf, "%s: running %s", blurb(), av[0]); + perror (buf); + } + + /* Note that one must use _exit() instead of exit() in procs forked + off of Gtk programs -- Gtk installs an atexit handler that has a + copy of the X connection (which we've already closed, for safety.) + If one uses exit() instead of _exit(), then one sometimes gets a + spurious "Gdk-ERROR: Fatal IO error on X server" error message. + */ + _exit (1); /* exits fork */ + break; + } + default: + { + int result = 0; + int wait_status = 0; + + FILE *f = fdopen (in, "r"); + unsigned int v = 0; + char c; + + close (out); /* don't need this one */ + + *buf = 0; + if (!fgets (buf, sizeof(buf)-1, f)) + *buf = 0; + fclose (f); + + /* Wait for the child to die. */ + waitpid (-1, &wait_status, 0); + + if (1 == sscanf (buf, "0x%x %c", &v, &c)) + result = (int) v; + + if (result == 0) + { + if (s->debug_p) + fprintf (stderr, "%s: %s did not report a GL visual!\n", + blurb(), av[0]); + return 0; + } + else + { + Visual *v = id_to_visual (DefaultScreenOfDisplay (dpy), result); + if (s->debug_p) + fprintf (stderr, "%s: %s says the GL visual is 0x%X.\n", + blurb(), av[0], result); + if (!v) abort(); + return v; + } + } + } + + abort(); +} + + +static void +kill_preview_subproc (state *s, Bool reset_p) +{ + s->running_preview_error_p = False; + + reap_zombies (s); + clear_preview_window (s); + + if (s->subproc_check_timer_id) + { + gtk_timeout_remove (s->subproc_check_timer_id); + s->subproc_check_timer_id = 0; + s->subproc_check_countdown = 0; + } + + if (s->running_preview_pid) + { + int status = kill (s->running_preview_pid, SIGTERM); + char *ss = subproc_pretty_name (s); + + if (status < 0) + { + if (errno == ESRCH) + { + if (s->debug_p) + fprintf (stderr, "%s: pid %lu (%s) was already dead.\n", + blurb(), (unsigned long) s->running_preview_pid, ss); + } + else + { + char buf [1024]; + sprintf (buf, "%s: couldn't kill pid %lu (%s)", + blurb(), (unsigned long) s->running_preview_pid, ss); + perror (buf); + } + } + 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; + if (s->running_preview_cmd) free (s->running_preview_cmd); + s->running_preview_cmd = 0; + } + + reap_zombies (s); + + if (reset_p) + { + reset_preview_window (s); + clear_preview_window (s); + } +} + + +/* Immediately and unconditionally launches the given process, + after appending the -window-id option; sets running_preview_pid. + */ +static void +launch_preview_subproc (state *s) +{ + saver_preferences *p = &s->prefs; + Window id; + char *new_cmd = 0; + pid_t forked; + const char *cmd = s->desired_preview_cmd; + + GtkWidget *pr = name_to_widget (s, "preview"); + GdkWindow *window; + + reset_preview_window (s); + + window = GET_WINDOW (pr); + + s->running_preview_error_p = False; + + if (s->preview_suppressed_p) + { + kill_preview_subproc (s, False); + goto DONE; + } + + new_cmd = malloc (strlen (cmd) + 40); + + id = (window ? GDK_WINDOW_XWINDOW (window) : 0); + if (id == 0) + { + /* No window id? No command to run. */ + free (new_cmd); + new_cmd = 0; + } + else + { + strcpy (new_cmd, cmd); + sprintf (new_cmd + strlen (new_cmd), " -window-id 0x%X", + (unsigned int) id); + } + + kill_preview_subproc (s, False); + if (! new_cmd) + { + s->running_preview_error_p = True; + clear_preview_window (s); + goto DONE; + } + + switch ((int) (forked = fork ())) + { + case -1: + { + char buf[255]; + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + s->running_preview_error_p = True; + goto DONE; + break; + } + case 0: + { + close (ConnectionNumber (GDK_DISPLAY())); + + hack_subproc_environment (id, s->debug_p); + + usleep (250000); /* pause for 1/4th second before launching, to give + the previous program time to die and flush its X + buffer, so we don't get leftover turds on the + window. */ + + exec_command (p->shell, new_cmd, p->nice_inferior); + /* Don't bother printing an error message when we are unable to + exec subprocesses; we handle that by polling the pid later. + + Note that one must use _exit() instead of exit() in procs forked + off of Gtk programs -- Gtk installs an atexit handler that has a + copy of the X connection (which we've already closed, for safety.) + If one uses exit() instead of _exit(), then one sometimes gets a + spurious "Gdk-ERROR: Fatal IO error on X server" error message. + */ + _exit (1); /* exits child fork */ + break; + + default: + + if (s->running_preview_cmd) free (s->running_preview_cmd); + s->running_preview_cmd = strdup (s->desired_preview_cmd); + s->running_preview_pid = forked; + + if (s->debug_p) + { + char *ss = subproc_pretty_name (s); + fprintf (stderr, "%s: forked %lu (%s)\n", blurb(), + (unsigned long) forked, ss); + free (ss); + } + break; + } + } + + schedule_preview_check (s); + + DONE: + if (new_cmd) free (new_cmd); + new_cmd = 0; +} + + +/* Modify $DISPLAY and $PATH for the benefit of subprocesses. + */ +static void +hack_environment (state *s) +{ + static const char *def_path = +# ifdef DEFAULT_PATH_PREFIX + DEFAULT_PATH_PREFIX; +# else + ""; +# endif + + Display *dpy = GDK_DISPLAY(); + const char *odpy = DisplayString (dpy); + char *ndpy = (char *) malloc(strlen(odpy) + 20); + strcpy (ndpy, "DISPLAY="); + strcat (ndpy, odpy); + if (putenv (ndpy)) + abort (); + + if (s->debug_p) + fprintf (stderr, "%s: %s\n", blurb(), ndpy); + + /* don't free(ndpy) -- some implementations of putenv (BSD 4.4, glibc + 2.0) copy the argument, but some (libc4,5, glibc 2.1.2) do not. + So we must leak it (and/or the previous setting). Yay. + */ + + if (def_path && *def_path) + { + const char *opath = getenv("PATH"); + char *npath = (char *) malloc(strlen(def_path) + strlen(opath) + 20); + strcpy (npath, "PATH="); + strcat (npath, def_path); + strcat (npath, ":"); + strcat (npath, opath); + + if (putenv (npath)) + abort (); + /* do not free(npath) -- see above */ + + if (s->debug_p) + fprintf (stderr, "%s: added \"%s\" to $PATH\n", blurb(), def_path); + } +} + + +static void +hack_subproc_environment (Window preview_window_id, Bool debug_p) +{ + /* Store a window ID in $XSCREENSAVER_WINDOW -- this isn't strictly + necessary yet, but it will make programs work if we had invoked + them with "-root" and not with "-window-id" -- which, of course, + doesn't happen. + */ + char *nssw = (char *) malloc (40); + sprintf (nssw, "XSCREENSAVER_WINDOW=0x%X", (unsigned int) preview_window_id); + + /* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems + any more, right? It's not Posix, but everyone seems to have it. */ + if (putenv (nssw)) + abort (); + + if (debug_p) + fprintf (stderr, "%s: %s\n", blurb(), nssw); + + /* do not free(nssw) -- see above */ +} + + +/* Called from a timer: + Launches the currently-chosen subprocess, if it's not already running. + If there's a different process running, kills it. + */ +static int +update_subproc_timer (gpointer data) +{ + state *s = (state *) data; + if (! s->desired_preview_cmd) + kill_preview_subproc (s, True); + else if (!s->running_preview_cmd || + !!strcmp (s->desired_preview_cmd, s->running_preview_cmd)) + launch_preview_subproc (s); + + s->subproc_timer_id = 0; + return FALSE; /* do not re-execute timer */ +} + +static int +settings_timer (gpointer data) +{ + settings_cb (0, 0); + return FALSE; +} + + +/* Call this when you think you might want a preview process running. + It will set a timer that will actually launch that program a second + from now, if you haven't changed your mind (to avoid double-click + spazzing, etc.) `cmd' may be null meaning "no process". + */ +static void +schedule_preview (state *s, const char *cmd) +{ + int delay = 1000 * 0.5; /* 1/2 second hysteresis */ + + if (s->debug_p) + { + if (cmd) + fprintf (stderr, "%s: scheduling preview \"%s\"\n", blurb(), cmd); + else + fprintf (stderr, "%s: scheduling preview death\n", blurb()); + } + + if (s->desired_preview_cmd) free (s->desired_preview_cmd); + s->desired_preview_cmd = (cmd ? strdup (cmd) : 0); + + if (s->subproc_timer_id) + gtk_timeout_remove (s->subproc_timer_id); + s->subproc_timer_id = gtk_timeout_add (delay, update_subproc_timer, s); +} + + +/* Called from a timer: + Checks to see if the subproc that should be running, actually is. + */ +static int +check_subproc_timer (gpointer data) +{ + state *s = (state *) data; + Bool again_p = True; + + if (s->running_preview_error_p || /* already dead */ + s->running_preview_pid <= 0) + { + again_p = False; + } + else + { + int status; + reap_zombies (s); + status = kill (s->running_preview_pid, 0); + if (status < 0 && errno == ESRCH) + s->running_preview_error_p = True; + + if (s->debug_p) + { + char *ss = subproc_pretty_name (s); + fprintf (stderr, "%s: timer: pid %lu (%s) is %s\n", blurb(), + (unsigned long) s->running_preview_pid, ss, + (s->running_preview_error_p ? "dead" : "alive")); + free (ss); + } + + if (s->running_preview_error_p) + { + clear_preview_window (s); + again_p = False; + } + } + + /* Otherwise, it's currently alive. We might be checking again, or we + might be satisfied. */ + + if (--s->subproc_check_countdown <= 0) + again_p = False; + + if (again_p) + return TRUE; /* re-execute timer */ + else + { + s->subproc_check_timer_id = 0; + s->subproc_check_countdown = 0; + return FALSE; /* do not re-execute timer */ + } +} + + +/* Call this just after launching a subprocess. + This sets a timer that will, five times a second for two seconds, + check whether the program is still running. The assumption here + is that if the process didn't stay up for more than a couple of + seconds, then either the program doesn't exist, or it doesn't + take a -window-id argument. + */ +static void +schedule_preview_check (state *s) +{ + int seconds = 2; + int ticks = 5; + + if (s->debug_p) + fprintf (stderr, "%s: scheduling check\n", blurb()); + + if (s->subproc_check_timer_id) + gtk_timeout_remove (s->subproc_check_timer_id); + s->subproc_check_timer_id = + gtk_timeout_add (1000 / ticks, + check_subproc_timer, (gpointer) s); + s->subproc_check_countdown = ticks * seconds; +} + + +static Bool +screen_blanked_p (void) +{ + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *dataP = 0; + Display *dpy = GDK_DISPLAY(); + Bool blanked_p = False; + + if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */ + XA_SCREENSAVER_STATUS, + 0, 3, False, XA_INTEGER, + &type, &format, &nitems, &bytesafter, + &dataP) + == Success + && type == XA_INTEGER + && nitems >= 3 + && dataP) + { + Atom *data = (Atom *) dataP; + blanked_p = (data[0] == XA_BLANK || data[0] == XA_LOCK); + } + + if (dataP) XFree (dataP); + + return blanked_p; +} + +/* Wake up every now and then and see if the screen is blanked. + If it is, kill off the small-window demo -- no point in wasting + cycles by running two screensavers at once... + */ +static int +check_blanked_timer (gpointer data) +{ + state *s = (state *) data; + Bool blanked_p = screen_blanked_p (); + if (blanked_p && s->running_preview_pid) + { + if (s->debug_p) + fprintf (stderr, "%s: screen is blanked: killing preview\n", blurb()); + kill_preview_subproc (s, True); + } + + return True; /* re-execute timer */ +} + + +/* How many screens are there (including Xinerama.) + */ +static int +screen_count (Display *dpy) +{ + int nscreens = ScreenCount(dpy); +# ifdef HAVE_XINERAMA + if (nscreens <= 1) + { + int event_number, error_number; + if (XineramaQueryExtension (dpy, &event_number, &error_number) && + XineramaIsActive (dpy)) + { + XineramaScreenInfo *xsi = XineramaQueryScreens (dpy, &nscreens); + if (xsi) XFree (xsi); + } + } +# endif /* HAVE_XINERAMA */ + + return nscreens; +} + + +/* Setting window manager icon + */ + +static void +init_icon (GdkWindow *window) +{ + GdkBitmap *mask = 0; + GdkColor transp; + GdkPixmap *pixmap = + gdk_pixmap_create_from_xpm_d (window, &mask, &transp, + (gchar **) logo_50_xpm); + if (pixmap) + gdk_window_set_icon (window, 0, pixmap, mask); +} + + +/* The main demo-mode command loop. + */ + +#if 0 +static Bool +mapper (XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks, + XrmRepresentation *type, XrmValue *value, XPointer closure) +{ + int i; + for (i = 0; quarks[i]; i++) + { + if (bindings[i] == XrmBindTightly) + fprintf (stderr, (i == 0 ? "" : ".")); + else if (bindings[i] == XrmBindLoosely) + fprintf (stderr, "*"); + else + fprintf (stderr, " ??? "); + fprintf(stderr, "%s", XrmQuarkToString (quarks[i])); + } + + fprintf (stderr, ": %s\n", (char *) value->addr); + + return False; +} +#endif + + +static Window +gnome_screensaver_window (Screen *screen) +{ + Display *dpy = DisplayOfScreen (screen); + Window root = RootWindowOfScreen (screen); + Window parent, *kids; + unsigned int nkids; + Window gnome_window = 0; + int i; + + if (! XQueryTree (dpy, root, &root, &parent, &kids, &nkids)) + abort (); + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *name; + if (XGetWindowProperty (dpy, kids[i], XA_WM_COMMAND, 0, 128, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, &name) + == Success + && type != None + && !strcmp ((char *) name, "gnome-screensaver")) + { + gnome_window = kids[i]; + break; + } + } + + if (kids) XFree ((char *) kids); + return gnome_window; +} + +static Bool +gnome_screensaver_active_p (void) +{ + Display *dpy = GDK_DISPLAY(); + Window w = gnome_screensaver_window (DefaultScreenOfDisplay (dpy)); + return (w ? True : False); +} + +static void +kill_gnome_screensaver (void) +{ + Display *dpy = GDK_DISPLAY(); + Window w = gnome_screensaver_window (DefaultScreenOfDisplay (dpy)); + if (w) XKillClient (dpy, (XID) w); +} + +static Bool +kde_screensaver_active_p (void) +{ + FILE *p = popen ("dcop kdesktop KScreensaverIface isEnabled 2>/dev/null", + "r"); + char buf[255]; + fgets (buf, sizeof(buf)-1, p); + pclose (p); + if (!strcmp (buf, "true\n")) + return True; + else + return False; +} + +static void +kill_kde_screensaver (void) +{ + system ("dcop kdesktop KScreensaverIface enable false"); +} + + +static void +the_network_is_not_the_computer (state *s) +{ + Display *dpy = GDK_DISPLAY(); + char *rversion = 0, *ruser = 0, *rhost = 0; + char *luser, *lhost; + char *msg = 0; + struct passwd *p = getpwuid (getuid ()); + const char *d = DisplayString (dpy); + +# if defined(HAVE_UNAME) + struct utsname uts; + if (uname (&uts) < 0) + lhost = ""; + else + lhost = uts.nodename; +# elif defined(VMS) + strcpy (lhost, getenv("SYS$NODE")); +# else /* !HAVE_UNAME && !VMS */ + strcat (lhost, ""); +# endif /* !HAVE_UNAME && !VMS */ + + if (p && p->pw_name) + luser = p->pw_name; + else + luser = "???"; + + server_xscreensaver_version (dpy, &rversion, &ruser, &rhost); + + /* Make a buffer that's big enough for a number of copies of all the + strings, plus some. */ + msg = (char *) malloc (10 * ((rversion ? strlen(rversion) : 0) + + (ruser ? strlen(ruser) : 0) + + (rhost ? strlen(rhost) : 0) + + strlen(lhost) + + strlen(luser) + + strlen(d) + + 1024)); + *msg = 0; + + if (!rversion || !*rversion) + { + sprintf (msg, + _("Warning:\n\n" + "The XScreenSaver daemon doesn't seem to be running\n" + "on display \"%s\". Launch it now?"), + d); + } + else if (p && ruser && *ruser && !!strcmp (ruser, p->pw_name)) + { + /* Warn that the two processes are running as different users. + */ + sprintf(msg, + _("Warning:\n\n" + "%s is running as user \"%s\" on host \"%s\".\n" + "But the xscreensaver managing display \"%s\"\n" + "is running as user \"%s\" on host \"%s\".\n" + "\n" + "Since they are different users, they won't be reading/writing\n" + "the same ~/.xscreensaver file, so %s isn't\n" + "going to work right.\n" + "\n" + "You should either re-run %s as \"%s\", or re-run\n" + "xscreensaver as \"%s\".\n" + "\n" + "Restart the xscreensaver daemon now?\n"), + progname, luser, lhost, + d, + (ruser ? ruser : "???"), (rhost ? rhost : "???"), + progname, + progname, (ruser ? ruser : "???"), + luser); + } + else if (rhost && *rhost && !!strcmp (rhost, lhost)) + { + /* Warn that the two processes are running on different hosts. + */ + sprintf (msg, + _("Warning:\n\n" + "%s is running as user \"%s\" on host \"%s\".\n" + "But the xscreensaver managing display \"%s\"\n" + "is running as user \"%s\" on host \"%s\".\n" + "\n" + "If those two machines don't share a file system (that is,\n" + "if they don't see the same ~%s/.xscreensaver file) then\n" + "%s won't work right.\n" + "\n" + "Restart the daemon on \"%s\" as \"%s\" now?\n"), + progname, luser, lhost, + d, + (ruser ? ruser : "???"), (rhost ? rhost : "???"), + luser, + progname, + lhost, luser); + } + else if (!!strcmp (rversion, s->short_version)) + { + /* Warn that the version numbers don't match. + */ + sprintf (msg, + _("Warning:\n\n" + "This is %s version %s.\n" + "But the xscreensaver managing display \"%s\"\n" + "is version %s. This could cause problems.\n" + "\n" + "Restart the xscreensaver daemon now?\n"), + progname, s->short_version, + d, + rversion); + } + + + if (*msg) + warning_dialog (s->toplevel_widget, msg, D_LAUNCH, 1); + + if (rversion) free (rversion); + if (ruser) free (ruser); + if (rhost) free (rhost); + free (msg); + msg = 0; + + /* Note: since these dialogs are not modal, they will stack up. + So we do this check *after* popping up the "xscreensaver is not + running" dialog so that these are on top. Good enough. + */ + + if (gnome_screensaver_active_p ()) + warning_dialog (s->toplevel_widget, + _("Warning:\n\n" + "The GNOME screensaver daemon appears to be running.\n" + "It must be stopped for XScreenSaver to work properly.\n" + "\n" + "Stop the GNOME screen saver daemon now?\n"), + D_GNOME, 1); + + if (kde_screensaver_active_p ()) + warning_dialog (s->toplevel_widget, + _("Warning:\n\n" + "The KDE screen saver daemon appears to be running.\n" + "It must be stopped for XScreenSaver to work properly.\n" + "\n" + "Stop the KDE screen saver daemon now?\n"), + D_KDE, 1); +} + + +/* We use this error handler so that X errors are preceeded by the name + of the program that generated them. + */ +static int +demo_ehandler (Display *dpy, XErrorEvent *error) +{ + state *s = global_state_kludge; /* I hate C so much... */ + fprintf (stderr, "\nX error in %s:\n", blurb()); + XmuPrintDefaultErrorMessage (dpy, error, stderr); + kill_preview_subproc (s, False); + exit (-1); + return 0; +} + + +/* We use this error handler so that Gtk/Gdk errors are preceeded by the name + of the program that generated them; and also that we can ignore one + particular bogus error message that Gdk madly spews. + */ +static void +g_log_handler (const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer user_data) +{ + /* Ignore the message "Got event for unknown window: 0x...". + Apparently some events are coming in for the xscreensaver window + (presumably reply events related to the ClientMessage) and Gdk + feels the need to complain about them. So, just suppress any + messages that look like that one. + */ + if (strstr (message, "unknown window")) + return; + + fprintf (stderr, "%s: %s-%s: %s%s", blurb(), + (log_domain ? log_domain : progclass), + (log_level == G_LOG_LEVEL_ERROR ? "error" : + log_level == G_LOG_LEVEL_CRITICAL ? "critical" : + log_level == G_LOG_LEVEL_WARNING ? "warning" : + log_level == G_LOG_LEVEL_MESSAGE ? "message" : + log_level == G_LOG_LEVEL_INFO ? "info" : + log_level == G_LOG_LEVEL_DEBUG ? "debug" : "???"), + message, + ((!*message || message[strlen(message)-1] != '\n') + ? "\n" : "")); +} + + +#ifdef __GNUC__ + __extension__ /* shut up about "string length is greater than the length + ISO C89 compilers are required to support" when including + the .ad file... */ +#endif + +STFU +static char *defaults[] = { +#include "XScreenSaver_ad.h" + 0 +}; + +#if 0 +#ifdef HAVE_CRAPPLET +static struct poptOption crapplet_options[] = { + {NULL, '\0', 0, NULL, 0} +}; +#endif /* HAVE_CRAPPLET */ +#endif /* 0 */ + +const char *usage = "[--display dpy] [--prefs | --settings]" +# ifdef HAVE_CRAPPLET + " [--crapplet]" +# endif + "\n\t\t [--debug] [--sync] [--no-xshm] [--configdir dir]"; + +static void +map_popup_window_cb (GtkWidget *w, gpointer user_data) +{ + state *s = (state *) user_data; + Boolean oi = s->initializing_p; +#ifndef HAVE_GTK2 + GtkLabel *label = GTK_LABEL (name_to_widget (s, "doc")); +#endif + s->initializing_p = True; +#ifndef HAVE_GTK2 + eschew_gtk_lossage (label); +#endif + s->initializing_p = oi; +} + + +#if 0 +static void +print_widget_tree (GtkWidget *w, int depth) +{ + int i; + for (i = 0; i < depth; i++) + fprintf (stderr, " "); + fprintf (stderr, "%s\n", gtk_widget_get_name (w)); + + if (GTK_IS_LIST (w)) + { + for (i = 0; i < depth+1; i++) + fprintf (stderr, " "); + fprintf (stderr, "...list kids...\n"); + } + else if (GTK_IS_CONTAINER (w)) + { + GList *kids = gtk_container_children (GTK_CONTAINER (w)); + while (kids) + { + print_widget_tree (GTK_WIDGET (kids->data), depth+1); + kids = kids->next; + } + } +} +#endif /* 0 */ + +static int +delayed_scroll_kludge (gpointer data) +{ + state *s = (state *) data; + GtkWidget *w = GTK_WIDGET (name_to_widget (s, "list")); + ensure_selected_item_visible (w); + + /* Oh, this is just fucking lovely, too. */ + w = GTK_WIDGET (name_to_widget (s, "preview")); + gtk_widget_hide (w); + gtk_widget_show (w); + + return FALSE; /* do not re-execute timer */ +} + +#ifdef HAVE_GTK2 + +GtkWidget * +create_xscreensaver_demo (void) +{ + GtkWidget *nb; + + nb = name_to_widget (global_state_kludge, "preview_notebook"); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), FALSE); + + return name_to_widget (global_state_kludge, "xscreensaver_demo"); +} + +GtkWidget * +create_xscreensaver_settings_dialog (void) +{ + GtkWidget *w, *box; + + box = name_to_widget (global_state_kludge, "dialog_action_area"); + + w = name_to_widget (global_state_kludge, "adv_button"); + gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (box), w, TRUE); + + w = name_to_widget (global_state_kludge, "std_button"); + gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (box), w, TRUE); + + return name_to_widget (global_state_kludge, "xscreensaver_settings_dialog"); +} + +#endif /* HAVE_GTK2 */ + +int +main (int argc, char **argv) +{ + XtAppContext app; + state S, *s; + saver_preferences *p; + Bool prefs_p = False; + Bool settings_p = False; + int i; + Display *dpy; + Widget toplevel_shell; + char *real_progname = argv[0]; + char *window_title; + char *geom = 0; + Bool crapplet_p = False; + char *str; + +#ifdef ENABLE_NLS + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + textdomain (GETTEXT_PACKAGE); + +# ifdef HAVE_GTK2 + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +# else /* !HAVE_GTK2 */ + if (!setlocale (LC_ALL, "")) + fprintf (stderr, "%s: locale not supported by C library\n", real_progname); +# endif /* !HAVE_GTK2 */ + +#endif /* ENABLE_NLS */ + + str = strrchr (real_progname, '/'); + if (str) real_progname = str+1; + + s = &S; + memset (s, 0, sizeof(*s)); + s->initializing_p = True; + p = &s->prefs; + + global_state_kludge = s; /* I hate C so much... */ + + progname = real_progname; + + s->short_version = (char *) malloc (5); + memcpy (s->short_version, screensaver_id + 17, 4); + s->short_version [4] = 0; + + + /* Register our error message logger for every ``log domain'' known. + There's no way to do this globally, so I grepped the Gtk/Gdk sources + for all of the domains that seem to be in use. + */ + { + const char * const domains[] = { 0, + "Gtk", "Gdk", "GLib", "GModule", + "GThread", "Gnome", "GnomeUI" }; + for (i = 0; i < countof(domains); i++) + g_log_set_handler (domains[i], G_LOG_LEVEL_MASK, g_log_handler, 0); + } + +#ifdef DEFAULT_ICONDIR /* from -D on compile line */ +# ifndef HAVE_GTK2 + { + const char *dir = DEFAULT_ICONDIR; + if (*dir) add_pixmap_directory (dir); + } +# endif /* !HAVE_GTK2 */ +#endif /* DEFAULT_ICONDIR */ + + /* This is gross, but Gtk understands --display and not -display... + */ + for (i = 1; i < argc; i++) + if (argv[i][0] && argv[i][1] && + !strncmp(argv[i], "-display", strlen(argv[i]))) + argv[i] = "--display"; + + + /* We need to parse this arg really early... Sigh. */ + for (i = 1; i < argc; i++) + { + if (argv[i] && + (!strcmp(argv[i], "--crapplet") || + !strcmp(argv[i], "--capplet"))) + { +# if defined(HAVE_CRAPPLET) || defined(HAVE_GTK2) + int j; + crapplet_p = True; + for (j = i; j < argc; j++) /* remove it from the list */ + argv[j] = argv[j+1]; + argc--; +# else /* !HAVE_CRAPPLET && !HAVE_GTK2 */ + fprintf (stderr, "%s: not compiled with --crapplet support\n", + real_progname); + fprintf (stderr, "%s: %s\n", real_progname, usage); + exit (1); +# endif /* !HAVE_CRAPPLET && !HAVE_GTK2 */ + } + else if (argv[i] && + (!strcmp(argv[i], "--debug") || + !strcmp(argv[i], "-debug") || + !strcmp(argv[i], "-d"))) + { + int j; + s->debug_p = True; + for (j = i; j < argc; j++) /* remove it from the list */ + argv[j] = argv[j+1]; + argc--; + i--; + } + else if (argv[i] && + argc > i+1 && + *argv[i+1] && + (!strcmp(argv[i], "-geometry") || + !strcmp(argv[i], "-geom") || + !strcmp(argv[i], "-geo") || + !strcmp(argv[i], "-g"))) + { + int j; + geom = argv[i+1]; + for (j = i; j < argc; j++) /* remove them from the list */ + argv[j] = argv[j+2]; + argc -= 2; + i -= 2; + } + else if (argv[i] && + argc > i+1 && + *argv[i+1] && + (!strcmp(argv[i], "--configdir"))) + { + int j; + struct stat st; + hack_configuration_path = argv[i+1]; + for (j = i; j < argc; j++) /* remove them from the list */ + argv[j] = argv[j+2]; + argc -= 2; + i -= 2; + + if (0 != stat (hack_configuration_path, &st)) + { + char buf[255]; + sprintf (buf, "%s: %.200s", blurb(), hack_configuration_path); + perror (buf); + exit (1); + } + else if (!S_ISDIR (st.st_mode)) + { + fprintf (stderr, "%s: not a directory: %s\n", + blurb(), hack_configuration_path); + exit (1); + } + } + } + + + if (s->debug_p) + fprintf (stderr, "%s: using config directory \"%s\"\n", + progname, hack_configuration_path); + + + /* Let Gtk open the X connection, then initialize Xt to use that + same connection. Doctor Frankenstein would be proud. + */ +# ifdef HAVE_CRAPPLET + if (crapplet_p) + { + GnomeClient *client; + GnomeClientFlags flags = 0; + + int init_results = gnome_capplet_init ("screensaver-properties", + s->short_version, + argc, argv, NULL, 0, NULL); + /* init_results is: + 0 upon successful initialization; + 1 if --init-session-settings was passed on the cmdline; + 2 if --ignore was passed on the cmdline; + -1 on error. + + So the 1 signifies just to init the settings, and quit, basically. + (Meaning launch the xscreensaver daemon.) + */ + + if (init_results < 0) + { +# if 0 + g_error ("An initialization error occurred while " + "starting xscreensaver-capplet.\n"); +# else /* !0 */ + fprintf (stderr, "%s: gnome_capplet_init failed: %d\n", + real_progname, init_results); + exit (1); +# endif /* !0 */ + } + + client = gnome_master_client (); + + if (client) + flags = gnome_client_get_flags (client); + + if (flags & GNOME_CLIENT_IS_CONNECTED) + { + int token = + gnome_startup_acquire_token ("GNOME_SCREENSAVER_PROPERTIES", + gnome_client_get_id (client)); + if (token) + { + char *session_args[20]; + int i = 0; + session_args[i++] = real_progname; + session_args[i++] = "--capplet"; + session_args[i++] = "--init-session-settings"; + session_args[i] = 0; + gnome_client_set_priority (client, 20); + gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY); + gnome_client_set_restart_command (client, i, session_args); + } + else + { + gnome_client_set_restart_style (client, GNOME_RESTART_NEVER); + } + + gnome_client_flush (client); + } + + if (init_results == 1) + { + system ("xscreensaver -nosplash &"); + return 0; + } + + } + else +# endif /* HAVE_CRAPPLET */ + { + gtk_init (&argc, &argv); + } + + + /* We must read exactly the same resources as xscreensaver. + That means we must have both the same progclass *and* progname, + at least as far as the resource database is concerned. So, + put "xscreensaver" in argv[0] while initializing Xt. + */ + argv[0] = "xscreensaver"; + progname = argv[0]; + + + /* Teach Xt to use the Display that Gtk/Gdk have already opened. + */ + XtToolkitInitialize (); + app = XtCreateApplicationContext (); + dpy = GDK_DISPLAY(); + XtAppSetFallbackResources (app, defaults); + XtDisplayInitialize (app, dpy, progname, progclass, 0, 0, &argc, argv); + toplevel_shell = XtAppCreateShell (progname, progclass, + applicationShellWidgetClass, + dpy, 0, 0); + + dpy = XtDisplay (toplevel_shell); + db = XtDatabase (dpy); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + XSetErrorHandler (demo_ehandler); + + /* Let's just ignore these. They seem to confuse Irix Gtk... */ + signal (SIGPIPE, SIG_IGN); + + /* After doing Xt-style command-line processing, complain about any + unrecognized command-line arguments. + */ + for (i = 1; i < argc; i++) + { + char *str = argv[i]; + if (str[0] == '-' && str[1] == '-') + str++; + if (!strcmp (str, "-prefs")) + prefs_p = True; + else if (!strcmp (str, "-settings")) + settings_p = True; + else if (crapplet_p) + /* There are lots of random args that we don't care about when we're + started as a crapplet, so just ignore unknown args in that case. */ + ; + else + { + fprintf (stderr, _("%s: unknown option: %s\n"), real_progname, + argv[i]); + fprintf (stderr, "%s: %s\n", real_progname, usage); + exit (1); + } + } + + /* Load the init file, which may end up consulting the X resource database + and the site-wide app-defaults file. Note that at this point, it's + important that `progname' be "xscreensaver", rather than whatever + was in argv[0]. + */ + p->db = db; + s->nscreens = screen_count (dpy); + + hack_environment (s); /* must be before initialize_sort_map() */ + + load_init_file (dpy, p); + initialize_sort_map (s); + + /* Now that Xt has been initialized, and the resources have been read, + we can set our `progname' variable to something more in line with + reality. + */ + progname = real_progname; + + +#if 0 + /* Print out all the resources we read. */ + { + XrmName name = { 0 }; + XrmClass class = { 0 }; + int count = 0; + XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper, + (POINTER) &count); + } +#endif + + + /* Intern the atoms that xscreensaver_command() needs. + */ + XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False); + XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False); + XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False); + XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False); + XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False); + XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False); + XA_SELECT = XInternAtom (dpy, "SELECT", False); + XA_DEMO = XInternAtom (dpy, "DEMO", False); + XA_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False); + XA_BLANK = XInternAtom (dpy, "BLANK", False); + XA_LOCK = XInternAtom (dpy, "LOCK", False); + XA_EXIT = XInternAtom (dpy, "EXIT", False); + XA_RESTART = XInternAtom (dpy, "RESTART", False); + + + /* Create the window and all its widgets. + */ + s->base_widget = create_xscreensaver_demo (); + s->popup_widget = create_xscreensaver_settings_dialog (); + s->toplevel_widget = s->base_widget; + + + /* Set the main window's title. */ + { + char *base_title = _("Screensaver Preferences"); + char *v = (char *) strdup(strchr(screensaver_id, ' ')); + char *s1, *s2, *s3, *s4; + s1 = (char *) strchr(v, ' '); s1++; + s2 = (char *) strchr(s1, ' '); + s3 = (char *) strchr(v, '('); s3++; + s4 = (char *) strchr(s3, ')'); + *s2 = 0; + *s4 = 0; + + window_title = (char *) malloc (strlen (base_title) + + strlen (progclass) + + strlen (s1) + strlen (s3) + + 100); + sprintf (window_title, "%s (%s %s, %s)", base_title, progclass, s1, s3); + gtk_window_set_title (GTK_WINDOW (s->toplevel_widget), window_title); + gtk_window_set_title (GTK_WINDOW (s->popup_widget), window_title); + free (v); + } + + /* Adjust the (invisible) notebooks on the popup dialog... */ + { + GtkNotebook *notebook = + GTK_NOTEBOOK (name_to_widget (s, "opt_notebook")); + GtkWidget *std = GTK_WIDGET (name_to_widget (s, "std_button")); + int page = 0; + +# ifdef HAVE_XML + gtk_widget_hide (std); +# else /* !HAVE_XML */ + /* Make the advanced page be the only one available. */ + gtk_widget_set_sensitive (std, False); + std = GTK_WIDGET (name_to_widget (s, "adv_button")); + gtk_widget_hide (std); + std = GTK_WIDGET (name_to_widget (s, "reset_button")); + gtk_widget_hide (std); + page = 1; +# endif /* !HAVE_XML */ + + gtk_notebook_set_page (notebook, page); + gtk_notebook_set_show_tabs (notebook, False); + } + + /* Various other widget initializations... + */ + gtk_signal_connect (GTK_OBJECT (s->toplevel_widget), "delete_event", + GTK_SIGNAL_FUNC (wm_toplevel_close_cb), + (gpointer) s); + gtk_signal_connect (GTK_OBJECT (s->popup_widget), "delete_event", + GTK_SIGNAL_FUNC (wm_popup_close_cb), + (gpointer) s); + + populate_hack_list (s); + populate_prefs_page (s); + sensitize_demo_widgets (s, False); + fix_text_entry_sizes (s); + scroll_to_current_hack (s); + + gtk_signal_connect (GTK_OBJECT (name_to_widget (s, "cancel_button")), + "map", GTK_SIGNAL_FUNC(map_popup_window_cb), + (gpointer) s); + +#ifndef HAVE_GTK2 + gtk_signal_connect (GTK_OBJECT (name_to_widget (s, "prev")), + "map", GTK_SIGNAL_FUNC(map_prev_button_cb), + (gpointer) s); + gtk_signal_connect (GTK_OBJECT (name_to_widget (s, "next")), + "map", GTK_SIGNAL_FUNC(map_next_button_cb), + (gpointer) s); +#endif /* !HAVE_GTK2 */ + + /* Hook up callbacks to the items on the mode menu. */ + { + GtkOptionMenu *opt = GTK_OPTION_MENU (name_to_widget (s, "mode_menu")); + GtkMenu *menu = GTK_MENU (gtk_option_menu_get_menu (opt)); + GList *kids = gtk_container_children (GTK_CONTAINER (menu)); + int i; + for (i = 0; kids; kids = kids->next, i++) + { + gtk_signal_connect (GTK_OBJECT (kids->data), "activate", + GTK_SIGNAL_FUNC (mode_menu_item_cb), + (gpointer) s); + + /* The "random-same" mode menu item does not appear unless + there are multple screens. + */ + if (s->nscreens <= 1 && + mode_menu_order[i] == RANDOM_HACKS_SAME) + gtk_widget_hide (GTK_WIDGET (kids->data)); + } + + if (s->nscreens <= 1) /* recompute option-menu size */ + { + gtk_widget_unrealize (GTK_WIDGET (menu)); + gtk_widget_realize (GTK_WIDGET (menu)); + } + } + + + /* Handle the -prefs command-line argument. */ + if (prefs_p) + { + GtkNotebook *notebook = + GTK_NOTEBOOK (name_to_widget (s, "notebook")); + gtk_notebook_set_page (notebook, 1); + } + +# ifdef HAVE_CRAPPLET + if (crapplet_p) + { + GtkWidget *capplet; + GtkWidget *outer_vbox; + + gtk_widget_hide (s->toplevel_widget); + + capplet = capplet_widget_new (); + + /* Make there be a "Close" button instead of "OK" and "Cancel" */ +# ifdef HAVE_CRAPPLET_IMMEDIATE + capplet_widget_changes_are_immediate (CAPPLET_WIDGET (capplet)); +# endif /* HAVE_CRAPPLET_IMMEDIATE */ + /* In crapplet-mode, take off the menubar. */ + gtk_widget_hide (name_to_widget (s, "menubar")); + + /* Reparent our top-level container to be a child of the capplet + window. + */ + outer_vbox = GTK_BIN (s->toplevel_widget)->child; + gtk_widget_ref (outer_vbox); + gtk_container_remove (GTK_CONTAINER (s->toplevel_widget), + outer_vbox); + STFU GTK_OBJECT_SET_FLAGS (outer_vbox, GTK_FLOATING); + gtk_container_add (GTK_CONTAINER (capplet), outer_vbox); + + /* Find the window above us, and set the title and close handler. */ + { + GtkWidget *window = capplet; + while (window && !GTK_IS_WINDOW (window)) + window = GET_PARENT (window); + if (window) + { + gtk_window_set_title (GTK_WINDOW (window), window_title); + gtk_signal_connect (GTK_OBJECT (window), "delete_event", + GTK_SIGNAL_FUNC (wm_toplevel_close_cb), + (gpointer) s); + } + } + + s->toplevel_widget = capplet; + } +# endif /* HAVE_CRAPPLET */ + + + /* The Gnome folks hate the menubar. I think it's important to have access + to the commands on the File menu (Restart Daemon, etc.) and to the + About and Documentation commands on the Help menu. + */ +#if 0 +#ifdef HAVE_GTK2 + gtk_widget_hide (name_to_widget (s, "menubar")); +#endif +#endif + + free (window_title); + window_title = 0; + +#ifdef HAVE_GTK2 + /* After picking the default size, allow -geometry to override it. */ + if (geom) + gtk_window_parse_geometry (GTK_WINDOW (s->toplevel_widget), geom); +#endif + + gtk_widget_show (s->toplevel_widget); + init_icon (GET_WINDOW (GTK_WIDGET (s->toplevel_widget))); /* after `show' */ + fix_preview_visual (s); + + /* Realize page zero, so that we can diddle the scrollbar when the + user tabs back to it -- otherwise, the current hack isn't scrolled + to the first time they tab back there, when started with "-prefs". + (Though it is if they then tab away, and back again.) + + #### Bah! This doesn't work. Gtk eats my ass! Someone who + #### understands this crap, explain to me how to make this work. + */ + gtk_widget_realize (name_to_widget (s, "demos_table")); + + + gtk_timeout_add (60 * 1000, check_blanked_timer, s); + + + /* Handle the --settings command-line argument. */ + if (settings_p) + gtk_timeout_add (500, settings_timer, 0); + + + /* Issue any warnings about the running xscreensaver daemon. */ + if (! s->debug_p) + the_network_is_not_the_computer (s); + + + if (senescent_p()) + warning_dialog (s->toplevel_widget, + _("Warning:\n\n" + "This version of xscreensaver is VERY OLD!\n" + "Please upgrade!\n" + "\n" + "http://www.jwz.org/xscreensaver/\n" + "\n" + "(If this is the latest version that your distro ships, then\n" + "your distro is doing you a disservice. Build from source.)\n" + ), + D_NONE, 7); + + + /* Run the Gtk event loop, and not the Xt event loop. This means that + if there were Xt timers or fds registered, they would never get serviced, + and if there were any Xt widgets, they would never have events delivered. + Fortunately, we're using Gtk for all of the UI, and only initialized + Xt so that we could process the command line and use the X resource + manager. + */ + s->initializing_p = False; + + /* This totally sucks -- set a timer that whacks the scrollbar 0.5 seconds + after we start up. Otherwise, it always appears scrolled to the top + when in crapplet-mode. */ + gtk_timeout_add (500, delayed_scroll_kludge, s); + + +#if 1 + /* Load every configurator in turn, to scan them for errors all at once. */ + 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 + + +# ifdef HAVE_CRAPPLET + if (crapplet_p) + capplet_gtk_main (); + else +# endif /* HAVE_CRAPPLET */ + gtk_main (); + + kill_preview_subproc (s, False); + exit (0); +} + +#endif /* HAVE_GTK -- whole file */ diff --git a/driver/demo-Xm-widgets.c b/driver/demo-Xm-widgets.c new file mode 100644 index 00000000..cbe33934 --- /dev/null +++ b/driver/demo-Xm-widgets.c @@ -0,0 +1,907 @@ +/* demo-Xm.c --- implements the interactive demo-mode and options dialogs. + * xscreensaver, Copyright (c) 1999, 2003 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include /* just for debug info */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_XMCOMBOBOX /* a Motif 2.0 widget */ +# include +# ifndef XmNtextField /* Lesstif 0.89.4 bug */ +# undef HAVE_XMCOMBOBOX +# endif +#endif /* HAVE_XMCOMBOBOX */ + +#include +#include + + + +const char *visual_menu[] = { + "Any", "Best", "Default", "Default-N", "GL", "TrueColor", "PseudoColor", + "StaticGray", "GrayScale", "DirectColor", "Color", "Gray", "Mono", 0 +}; + + + +static Widget create_demos_page (Widget parent); +static Widget create_options_page (Widget parent); + +static void +tab_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + Widget parent = XtParent(button); + Widget tabber = XtNameToWidget (parent, "*folder"); + Widget this_tab = (Widget) client_data; + Widget *kids = 0; + Cardinal nkids = 0; + if (!tabber) abort(); + + XtVaGetValues (tabber, XmNnumChildren, &nkids, XmNchildren, &kids, NULL); + if (!kids) abort(); + if (nkids > 0) + XtUnmanageChildren (kids, nkids); + + XtManageChild (this_tab); +} + + +Widget +create_xscreensaver_demo (Widget parent) +{ + /* MainWindow + Form + Menubar + DemoTab + OptionsTab + HR + Tabber + (demo page) + (options page) + */ + + Widget mainw, form, menubar; + Widget demo_tab, options_tab, hr, tabber, demos, options; + Arg av[100]; + int ac = 0; + + mainw = XmCreateMainWindow (parent, "demoForm", av, ac); + form = XmCreateForm (mainw, "form", av, ac); + menubar = XmCreateSimpleMenuBar (form, "menubar", av, ac); + XtVaSetValues (menubar, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + NULL); + + { + Widget menu = 0, item = 0; + char *menus[] = { + "*file", "blank", "lock", "kill", "restart", "-", "exit", + "*edit", "cut", "copy", "paste", + "*help", "about", "docMenu" }; + int i; + for (i = 0; i < sizeof(menus)/sizeof(*menus); i++) + { + ac = 0; + if (menus[i][0] == '-') + item = XmCreateSeparatorGadget (menu, "separator", av, ac); + else if (menus[i][0] != '*') + item = XmCreatePushButtonGadget (menu, menus[i], av, ac); + else + { + menu = XmCreatePulldownMenu (parent, menus[i]+1, av, ac); + XtSetArg (av [ac], XmNsubMenuId, menu); ac++; + item = XmCreateCascadeButtonGadget (menubar, menus[i]+1, av, ac); + + if (!strcmp (menus[i]+1, "help")) + XtVaSetValues(menubar, XmNmenuHelpWidget, item, NULL); + } + XtManageChild (item); + } + ac = 0; + } + + demo_tab = XmCreatePushButtonGadget (form, "demoTab", av, ac); + XtVaSetValues (demo_tab, + XmNleftAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, menubar, + NULL); + + options_tab = XmCreatePushButtonGadget (form, "optionsTab", av, ac); + XtVaSetValues (options_tab, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, demo_tab, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopWidget, demo_tab, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomWidget, demo_tab, + NULL); + + hr = XmCreateSeparatorGadget (form, "hr", av, ac); + XtVaSetValues (hr, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, demo_tab, + NULL); + + tabber = XmCreateForm (form, "folder", av, ac); + XtVaSetValues (tabber, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, hr, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + demos = create_demos_page (tabber); + options = create_options_page (tabber); + + XtAddCallback (demo_tab, XmNactivateCallback, tab_cb, demos); + XtAddCallback (options_tab, XmNactivateCallback, tab_cb, options); + + XtManageChild (demos); + XtManageChild (options); + + XtManageChild (demo_tab); + XtManageChild (options_tab); + XtManageChild (hr); + XtManageChild (menubar); + XtManageChild (tabber); + XtManageChild (form); + +#if 1 + XtUnmanageChild (options); + XtManageChild (demos); +#endif + + return mainw; +} + + +static Widget +create_demos_page (Widget parent) +{ + /* Form1 (horizontal) + Form2 (vertical) + Scroller + List + ButtonBox1 (vertical) + Button ("Down") + Button ("Up") + Form3 (vertical) + Frame + Label + TextArea (doc) + Label + Text ("Command Line") + Form4 (horizontal) + Checkbox ("Enabled") + Label ("Visual") + ComboBox + HR + ButtonBox2 (vertical) + Button ("Demo") + Button ("Documentation") + */ + Widget form1, form2, form3, form4; + Widget scroller, list, buttonbox1, down, up; + Widget frame, frame_label, doc, cmd_label, cmd_text, enabled, vis_label; + Widget combo; + Widget hr, buttonbox2, demo, man; + Arg av[100]; + int ac = 0; + int i; + + form1 = XmCreateForm (parent, "form1", av, ac); + form2 = XmCreateForm (form1, "form2", av, ac); + XtVaSetValues (form2, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + scroller = XmCreateScrolledWindow (form2, "scroller", av, ac); + XtVaSetValues (scroller, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_WIDGET, + NULL); + list = XmCreateList (scroller, "list", av, ac); + + buttonbox1 = XmCreateForm (form2, "buttonbox1", av, ac); + XtVaSetValues (buttonbox1, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + XtVaSetValues (scroller, XmNbottomWidget, buttonbox1, NULL); + + down = XmCreatePushButton (buttonbox1, "down", av, ac); + XtVaSetValues (down, + XmNleftAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + up = XmCreatePushButton (buttonbox1, "up", av, ac); + XtVaSetValues (up, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, down, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + form3 = XmCreateForm (form1, "form3", av, ac); + XtVaSetValues (form3, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, form2, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + frame = XmCreateFrame (form3, "frame", av, ac); + + ac = 0; + XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++; + frame_label = XmCreateLabelGadget (frame, "frameLabel", av, ac); + + ac = 0; + XtVaSetValues (frame, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_WIDGET, + NULL); + + ac = 0; + XtSetArg (av [ac], XmNchildType, XmFRAME_WORKAREA_CHILD); ac++; + doc = XmCreateText (frame, "doc", av, ac); + + ac = 0; + XtVaSetValues (doc, + XmNeditable, FALSE, + XmNcursorPositionVisible, FALSE, + XmNwordWrap, TRUE, + XmNeditMode, XmMULTI_LINE_EDIT, + XmNshadowThickness, 0, + NULL); + + cmd_label = XmCreateLabelGadget (form3, "cmdLabel", av, ac); + XtVaSetValues (cmd_label, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_WIDGET, + NULL); + XtVaSetValues (frame, XmNbottomWidget, cmd_label, NULL); + + cmd_text = XmCreateTextField (form3, "cmdText", av, ac); + XtVaSetValues (cmd_text, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_WIDGET, + NULL); + XtVaSetValues (cmd_label, XmNbottomWidget, cmd_text, NULL); + + form4 = XmCreateForm (form3, "form4", av, ac); + XtVaSetValues (form4, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_WIDGET, + NULL); + XtVaSetValues (cmd_text, XmNbottomWidget, form4, NULL); + + enabled = XmCreateToggleButtonGadget (form4, "enabled", av, ac); + XtVaSetValues (enabled, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + vis_label = XmCreateLabelGadget (form4, "visLabel", av, ac); + XtVaSetValues (vis_label, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, enabled, + XmNbottomAttachment, XmATTACH_FORM, + NULL); +#ifdef HAVE_XMCOMBOBOX + { + Widget list; + ac = 0; + XtSetArg (av [ac], XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); ac++; + combo = XmCreateComboBox (form4, "combo", av, ac); + for (i = 0; visual_menu[i]; i++) + { + XmString xs = XmStringCreate ((char *) visual_menu[i], + XmSTRING_DEFAULT_CHARSET); + XmComboBoxAddItem (combo, xs, 0, False); + XmStringFree (xs); + } + XtVaGetValues (combo, XmNlist, &list, NULL); + XtVaSetValues (list, XmNvisibleItemCount, i, NULL); + } +#else /* !HAVE_XMCOMBOBOX */ + { + Widget popup_menu = XmCreatePulldownMenu (parent, "menu", av, ac); + Widget kids[100]; + for (i = 0; visual_menu[i]; i++) + { + XmString xs = XmStringCreate ((char *) visual_menu[i], + XmSTRING_DEFAULT_CHARSET); + ac = 0; + XtSetArg (av [ac], XmNlabelString, xs); ac++; + kids[i] = XmCreatePushButtonGadget (popup_menu, "button", av, ac); + /* XtAddCallback (combo, XmNactivateCallback, visual_popup_cb, + combo); */ + XmStringFree (xs); + } + XtManageChildren (kids, i); + + ac = 0; + XtSetArg (av [ac], XmNsubMenuId, popup_menu); ac++; + combo = XmCreateOptionMenu (form4, "combo", av, ac); + ac = 0; + } +#endif /* !HAVE_XMCOMBOBOX */ + + XtVaSetValues (combo, + XmNtopAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, vis_label, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + hr = XmCreateSeparatorGadget (form3, "hr", av, ac); + XtVaSetValues (hr, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_WIDGET, + NULL); + XtVaSetValues (form4, XmNbottomWidget, hr, NULL); + + buttonbox2 = XmCreateForm (form3, "buttonbox2", av, ac); + XtVaSetValues (buttonbox2, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + XtVaSetValues (hr, XmNbottomWidget, buttonbox2, NULL); + + demo = XmCreatePushButtonGadget (buttonbox2, "demo", av, ac); + XtVaSetValues (demo, + XmNleftAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + man = XmCreatePushButtonGadget (buttonbox2, "man", av, ac); + XtVaSetValues (man, + XmNrightAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + XtManageChild (demo); + XtManageChild (man); + XtManageChild (buttonbox2); + XtManageChild (hr); + + XtManageChild (combo); + XtManageChild (vis_label); + XtManageChild (enabled); + XtManageChild (form4); + + XtManageChild (cmd_text); + XtManageChild (cmd_label); + + XtManageChild (doc); + XtManageChild (frame_label); + XtManageChild (frame); + XtManageChild (form3); + + XtManageChild (up); + XtManageChild (down); + XtManageChild (buttonbox1); + + XtManageChild (list); + XtManageChild (scroller); + XtManageChild (form2); + + XtManageChild (form1); + + XtVaSetValues (form1, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + return form1; +} + + + +static Widget +create_options_page (Widget parent) +{ + /* This is what the layout is today: + + Form (horizontal) + Label ("Saver Timeout") + Label ("Cycle Timeout") + Label ("Fade Duration") + Label ("Fade Ticks") + Label ("Lock Timeout") + Label ("Password Timeout") + + Text (timeout) + Text (cycle) + Text (fade seconds) + Text (fade ticks) + Text (lock) + Text (passwd) + + Toggle ("Verbose") + Toggle ("Install Colormap") + Toggle ("Fade Colormap") + Toggle ("Unfade Colormap") + Toggle ("Require Password") + + HR + Button ("OK") + Button ("Cancel") + */ + + /* This is what it should be: + + Form (horizontal) + Form (vertical) ("column1") + Frame + Label ("Blanking and Locking") + Form + Label ("Blank After") + Label ("Cycle After") + Text ("Blank After") + Text ("Cycle After") + HR + Checkbox ("Require Password") + Label ("Lock After") + Text ("Lock After") + Frame + Label ("Image Manipulation") + Form + Checkbox ("Grab Desktop Images") + Checkbox ("Grab Video Frames") + Checkbox ("Choose Random Image") + Text (pathname) + Button ("Browse") + Frame + Label ("Diagnostics") + Form + Checkbox ("Verbose Diagnostics") + Checkbox ("Display Subprocess Errors") + Checkbox ("Display Splash Screen at Startup") + Form (vertical) ("column2") + Frame + Label ("Display Power Management") + Form + Checkbox ("Power Management Enabled") + Label ("Standby After") + Label ("Suspend After") + Label ("Off After") + Text ("Standby After") + Text ("Suspend After") + Text ("Off After") + Frame + Label ("Colormaps") + Form + Checkbox ("Install Colormap") + HR + Checkbox ("Fade To Black When Blanking") + Checkbox ("Fade From Black When Unblanking") + Label ("Fade Duration") + Text ("Fade Duration") + + timeoutLabel + cycleLabel + fadeSecondsLabel + fadeTicksLabel + lockLabel + passwdLabel + + timeoutText + cycleText + fadeSecondsText + fadeTicksText + lockText + passwdText + + verboseToggle + cmapToggle + fadeToggle + unfadeToggle + lockToggle + + separator + OK + Cancel + */ + + + + Arg av[64]; + int ac = 0; + Widget children[100]; + Widget timeout_label, cycle_label, fade_seconds_label, fade_ticks_label; + Widget lock_label, passwd_label, hr; + Widget preferences_form; + + Widget timeout_text, cycle_text, fade_text, fade_ticks_text; + Widget lock_timeout_text, passwd_timeout_text, verbose_toggle; + Widget install_cmap_toggle, fade_toggle, unfade_toggle; + Widget lock_toggle, prefs_done, prefs_cancel; + + ac = 0; + XtSetArg (av [ac], XmNdialogType, XmDIALOG_PROMPT); ac++; + + ac = 0; + XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; + XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; + XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; + XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; + preferences_form = XmCreateForm (parent, "preferencesForm", av, ac); + XtManageChild (preferences_form); + + ac = 0; + + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; + timeout_label = XmCreateLabelGadget (preferences_form, "timeoutLabel", + av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; + cycle_label = XmCreateLabelGadget (preferences_form, "cycleLabel", + av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; + fade_seconds_label = XmCreateLabelGadget (preferences_form, + "fadeSecondsLabel", av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; + fade_ticks_label = XmCreateLabelGadget (preferences_form, "fadeTicksLabel", + av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; + lock_label = XmCreateLabelGadget (preferences_form, "lockLabel", av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; + passwd_label = XmCreateLabelGadget (preferences_form, "passwdLabel", av, ac); + ac = 0; + timeout_text = XmCreateTextField (preferences_form, "timeoutText", av, ac); + cycle_text = XmCreateTextField (preferences_form, "cycleText", av, ac); + fade_text = XmCreateTextField (preferences_form, "fadeSecondsText", av, ac); + fade_ticks_text = XmCreateTextField (preferences_form, "fadeTicksText", + av, ac); + lock_timeout_text = XmCreateTextField (preferences_form, "lockText", + av, ac); + passwd_timeout_text = XmCreateTextField (preferences_form, "passwdText", + av, ac); + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + verbose_toggle = XmCreateToggleButtonGadget (preferences_form, + "verboseToggle", av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + install_cmap_toggle = XmCreateToggleButtonGadget (preferences_form, + "cmapToggle", av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + fade_toggle = XmCreateToggleButtonGadget (preferences_form, "fadeToggle", + av, ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + unfade_toggle = XmCreateToggleButtonGadget (preferences_form, "unfadeToggle", + av,ac); + ac = 0; + XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; + lock_toggle = XmCreateToggleButtonGadget (preferences_form, "lockToggle", + av, ac); + ac = 0; + hr = XmCreateSeparatorGadget (preferences_form, "separator", av, ac); + + prefs_done = XmCreatePushButtonGadget (preferences_form, "OK", av, ac); + prefs_cancel = XmCreatePushButtonGadget (preferences_form, "Cancel", av, ac); + + XtVaSetValues (timeout_label, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 4, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomWidget, timeout_text, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 20, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightOffset, 4, + XmNrightWidget, timeout_text, + NULL); + + XtVaSetValues (cycle_label, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, cycle_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, cycle_text, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 20, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightOffset, 4, + XmNrightWidget, cycle_text, + NULL); + + XtVaSetValues (fade_seconds_label, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, fade_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, fade_text, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 20, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightOffset, 4, + XmNrightWidget, fade_text, + NULL); + + XtVaSetValues (fade_ticks_label, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, fade_ticks_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, fade_ticks_text, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 20, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightOffset, 4, + XmNrightWidget, fade_ticks_text, + NULL); + + XtVaSetValues (lock_label, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, lock_timeout_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, lock_timeout_text, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 19, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightOffset, 4, + XmNrightWidget, lock_timeout_text, + NULL); + + XtVaSetValues (passwd_label, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, passwd_timeout_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, passwd_timeout_text, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 14, + XmNrightAttachment, XmATTACH_WIDGET, + XmNrightOffset, 4, + XmNrightWidget, passwd_timeout_text, + NULL); + + XtVaSetValues (timeout_text, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 4, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 141, + NULL); + + XtVaSetValues (cycle_text, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopOffset, 2, + XmNtopWidget, timeout_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, timeout_text, + NULL); + + XtVaSetValues (fade_text, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopOffset, 2, + XmNtopWidget, cycle_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, cycle_text, + NULL); + + XtVaSetValues (fade_ticks_text, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopOffset, 2, + XmNtopWidget, fade_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, fade_text, + NULL); + + XtVaSetValues (lock_timeout_text, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopOffset, 2, + XmNtopWidget, fade_ticks_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, fade_ticks_text, + NULL); + + XtVaSetValues (passwd_timeout_text, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopOffset, 4, + XmNtopWidget, lock_timeout_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, lock_timeout_text, + NULL); + + XtVaSetValues (verbose_toggle, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 4, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, timeout_text, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftOffset, 20, + XmNleftWidget, timeout_text, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 20, + NULL); + + XtVaSetValues (install_cmap_toggle, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, cycle_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, cycle_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, verbose_toggle, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 20, + NULL); + + XtVaSetValues (fade_toggle, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, fade_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, fade_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, install_cmap_toggle, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 20, + NULL); + + XtVaSetValues (unfade_toggle, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, fade_ticks_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, fade_ticks_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, fade_toggle, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 20, + NULL); + + XtVaSetValues (lock_toggle, + XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNtopOffset, 0, + XmNtopWidget, lock_timeout_text, + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNbottomOffset, 0, + XmNbottomWidget, lock_timeout_text, + XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, + XmNleftOffset, 0, + XmNleftWidget, unfade_toggle, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 20, + NULL); + + XtVaSetValues (hr, + XmNtopWidget, passwd_timeout_text, + XmNbottomAttachment, XmATTACH_FORM, + XmNbottomOffset, 4, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + NULL); + + XtVaSetValues (prefs_done, + XmNleftAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + XtVaSetValues (prefs_cancel, + XmNrightAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + XtVaSetValues (hr, + XmNbottomAttachment, XmATTACH_WIDGET, + XmNbottomWidget, prefs_done, + NULL); + + ac = 0; + children[ac++] = timeout_label; + children[ac++] = cycle_label; + children[ac++] = fade_seconds_label; + children[ac++] = fade_ticks_label; + children[ac++] = lock_label; + children[ac++] = passwd_label; + children[ac++] = timeout_text; + children[ac++] = cycle_text; + children[ac++] = fade_text; + children[ac++] = fade_ticks_text; + children[ac++] = lock_timeout_text; + children[ac++] = passwd_timeout_text; + children[ac++] = verbose_toggle; + children[ac++] = install_cmap_toggle; + children[ac++] = fade_toggle; + children[ac++] = unfade_toggle; + children[ac++] = lock_toggle; + children[ac++] = hr; + + XtManageChildren(children, ac); + ac = 0; + + XtManageChild (prefs_done); + XtManageChild (prefs_cancel); + + XtManageChild (preferences_form); + + XtVaSetValues (preferences_form, + XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + NULL); + + return preferences_form; +} diff --git a/driver/demo-Xm.c b/driver/demo-Xm.c new file mode 100644 index 00000000..56d1aac5 --- /dev/null +++ b/driver/demo-Xm.c @@ -0,0 +1,1875 @@ +/* demo-Xm.c --- implements the interactive demo-mode and options dialogs. + * xscreensaver, Copyright (c) 1993-2003, 2005 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_MOTIF /* whole file */ + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifndef VMS +# include /* for getpwuid() */ +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + +#ifdef HAVE_UNAME +# include /* for uname() */ +#endif /* HAVE_UNAME */ + +#include + +#include /* for CARD32 */ +#include /* for XA_INTEGER */ +#include +#include + +/* We don't actually use any widget internals, but these are included + so that gdb will have debug info for the widgets... */ +#include +#include + +#ifdef HAVE_XPM +# include +#endif /* HAVE_XPM */ + +#ifdef HAVE_XMU +# ifndef VMS +# include +# else /* VMS */ +# include +# endif +#else +# include "xmu.h" +#endif + + + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_XMCOMBOBOX /* a Motif 2.0 widget */ +# include +# ifndef XmNtextField /* Lesstif 0.89.4 bug */ +# undef HAVE_XMCOMBOBOX +# endif +# if (XmVersion < 2001) /* Lesstif has two personalities these days */ +# undef HAVE_XMCOMBOBOX +# endif +#endif /* HAVE_XMCOMBOBOX */ + +#include "version.h" +#include "prefs.h" +#include "resources.h" /* for parse_time() */ +#include "visual.h" /* for has_writable_cells() */ +#include "remote.h" /* for xscreensaver_command() */ +#include "usleep.h" + +#include +#include +#include + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + + +char *progname = 0; +char *progclass = "XScreenSaver"; +XrmDatabase db; + +typedef struct { + saver_preferences *a, *b; +} prefs_pair; + +static void *global_prefs_pair; /* I hate C so much... */ + +char *blurb (void) { return progname; } + +extern Widget create_xscreensaver_demo (Widget parent); +extern const char *visual_menu[]; + + +static char *short_version = 0; + +Atom XA_VROOT; +Atom XA_SCREENSAVER, XA_SCREENSAVER_RESPONSE, XA_SCREENSAVER_VERSION; +Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO; +Atom XA_ACTIVATE, XA_BLANK, XA_LOCK, XA_RESTART, XA_EXIT; + + +static void populate_demo_window (Widget toplevel, + int which, prefs_pair *pair); +static void populate_prefs_page (Widget top, prefs_pair *pair); +static int apply_changes_and_save (Widget widget); +static int maybe_reload_init_file (Widget widget, prefs_pair *pair); +static void await_xscreensaver (Widget widget); + + +/* Some random utility functions + */ + +static Widget +name_to_widget (Widget widget, const char *name) +{ + Widget parent; + char name2[255]; + name2[0] = '*'; + strcpy (name2+1, name); + + while ((parent = XtParent (widget))) + widget = parent; + return XtNameToWidget (widget, name2); +} + + + +/* Why this behavior isn't automatic in *either* toolkit, I'll never know. + Takes a scroller, viewport, or list as an argument. + */ +static void +ensure_selected_item_visible (Widget list) +{ + int *pos_list = 0; + int pos_count = 0; + if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0) + { + int top = -2; + int visible = 0; + XtVaGetValues (list, + XmNtopItemPosition, &top, + XmNvisibleItemCount, &visible, + NULL); + if (pos_list[0] >= top + visible) + { + int pos = pos_list[0] - visible + 1; + if (pos < 0) pos = 0; + XmListSetPos (list, pos); + } + else if (pos_list[0] < top) + { + XmListSetPos (list, pos_list[0]); + } + } + if (pos_list) + XtFree ((char *) pos_list); +} + + +static void +warning_dialog_dismiss_cb (Widget button, XtPointer client_data, + XtPointer user_data) +{ + Widget shell = (Widget) client_data; + XtDestroyWidget (shell); +} + + +static void +warning_dialog (Widget parent, const char *message, int center) +{ + char *msg = strdup (message); + char *head; + + Widget dialog = 0; + Widget label = 0; + Widget ok = 0; + int i = 0; + + Widget w; + Widget container; + XmString xmstr; + Arg av[10]; + int ac = 0; + + ac = 0; + dialog = XmCreateWarningDialog (parent, "warning", av, ac); + + w = XmMessageBoxGetChild (dialog, XmDIALOG_MESSAGE_LABEL); + if (w) XtUnmanageChild (w); + w = XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON); + if (w) XtUnmanageChild (w); + w = XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON); + if (w) XtUnmanageChild (w); + + ok = XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON); + + ac = 0; + XtSetArg (av[ac], XmNnumColumns, 1); ac++; + XtSetArg (av[ac], XmNorientation, XmVERTICAL); ac++; + XtSetArg (av[ac], XmNpacking, XmPACK_COLUMN); ac++; + XtSetArg (av[ac], XmNrowColumnType, XmWORK_AREA); ac++; + XtSetArg (av[ac], XmNspacing, 0); ac++; + container = XmCreateRowColumn (dialog, "container", av, ac); + + head = msg; + while (head) + { + char name[20]; + char *s = strchr (head, '\n'); + if (s) *s = 0; + + sprintf (name, "label%d", i++); + + xmstr = XmStringCreate (head, XmSTRING_DEFAULT_CHARSET); + ac = 0; + XtSetArg (av[ac], XmNlabelString, xmstr); ac++; + XtSetArg (av[ac], XmNmarginHeight, 0); ac++; + label = XmCreateLabelGadget (container, name, av, ac); + XtManageChild (label); + XmStringFree (xmstr); + + if (s) + head = s+1; + else + head = 0; + + center--; + } + + XtManageChild (container); + XtRealizeWidget (dialog); + XtManageChild (dialog); + + XtAddCallback (ok, XmNactivateCallback, warning_dialog_dismiss_cb, dialog); + + free (msg); +} + + +static void +run_cmd (Widget widget, Atom command, int arg) +{ + char *err = 0; + int status; + + apply_changes_and_save (widget); + status = xscreensaver_command (XtDisplay (widget), + command, arg, False, &err); + if (status < 0) + { + char buf [255]; + if (err) + sprintf (buf, "Error:\n\n%s", err); + else + strcpy (buf, "Unknown error!"); + warning_dialog (widget, buf, 100); + } + if (err) free (err); +} + + +static void +run_hack (Widget widget, int which, Bool report_errors_p) +{ + if (which < 0) return; + apply_changes_and_save (widget); + if (report_errors_p) + run_cmd (widget, XA_DEMO, which + 1); + else + { + char *s = 0; + xscreensaver_command (XtDisplay (widget), XA_DEMO, which + 1, False, &s); + if (s) free (s); + } +} + + + +/* Button callbacks + */ + +void +exit_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + apply_changes_and_save (XtParent (button)); + exit (0); +} + +#if 0 +static void +wm_close_cb (Widget widget, GdkEvent *event, XtPointer data) +{ + apply_changes_and_save (XtParent (button)); + exit (0); +} +#endif + +void +cut_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + /* #### */ + warning_dialog (XtParent (button), + "Error:\n\n" + "cut unimplemented\n", 1); +} + + +void +copy_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + /* #### */ + warning_dialog (XtParent (button), + "Error:\n\n" + "copy unimplemented\n", 1); +} + + +void +paste_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + /* #### */ + warning_dialog (XtParent (button), + "Error:\n\n" + "paste unimplemented\n", 1); +} + + +void +about_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + char buf [2048]; + char *s = strdup (screensaver_id + 4); + char *s2; + + s2 = strchr (s, ','); + *s2 = 0; + s2 += 2; + + sprintf (buf, "%s\n%s\n" + "\n" + "This is the Motif version of \"xscreensaver-demo\". The Motif\n" + "version is no longer maintained. Please use the GTK version\n" + "instead, which has many more features.\n" + "\n" + "For xscreensaver updates, check http://www.jwz.org/xscreensaver/", + s, s2); + free (s); + + warning_dialog (XtParent (button), buf, 100); +} + + +void +doc_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; + + saver_preferences *p = pair->a; + char *help_command; + + if (!p->help_url || !*p->help_url) + { + warning_dialog (XtParent (button), + "Error:\n\n" + "No Help URL has been specified.\n", 100); + return; + } + + help_command = (char *) malloc (strlen (p->load_url_command) + + (strlen (p->help_url) * 4) + 20); + strcpy (help_command, "( "); + sprintf (help_command + strlen(help_command), + p->load_url_command, + p->help_url, p->help_url, p->help_url, p->help_url); + strcat (help_command, " ) &"); + system (help_command); + free (help_command); +} + + +void +activate_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + run_cmd (XtParent (button), XA_ACTIVATE, 0); +} + + +void +lock_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + run_cmd (XtParent (button), XA_LOCK, 0); +} + + +void +kill_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + run_cmd (XtParent (button), XA_EXIT, 0); +} + + +void +restart_menu_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ +#if 0 + run_cmd (XtParent (button), XA_RESTART, 0); +#else + button = XtParent (button); + apply_changes_and_save (button); + xscreensaver_command (XtDisplay (button), XA_EXIT, 0, False, NULL); + sleep (1); + system ("xscreensaver -nosplash &"); +#endif + + await_xscreensaver (button); +} + +static void +await_xscreensaver (Widget widget) +{ + int countdown = 5; + + Display *dpy = XtDisplay (widget); + char *rversion = 0; + + while (!rversion && (--countdown > 0)) + { + /* Check for the version of the running xscreensaver... */ + server_xscreensaver_version (dpy, &rversion, 0, 0); + + /* If it's not there yet, wait a second... */ + sleep (1); + } + + if (rversion) + { + /* Got it. */ + free (rversion); + } + else + { + /* Timed out, no screensaver running. */ + + char buf [1024]; + Bool root_p = (geteuid () == 0); + + strcpy (buf, + "Error:\n\n" + "The xscreensaver daemon did not start up properly.\n" + "\n"); + + if (root_p) +# ifdef __GNUC__ + __extension__ /* don't warn about "string length is greater than + the length ISO C89 compilers are required to + support" in the following expression... */ +# endif + strcat (buf, + "You are running as root. This usually means that xscreensaver\n" + "was unable to contact your X server because access control is\n" + "turned on. Try running this command:\n" + "\n" + " xhost +localhost\n" + "\n" + "and then selecting `File / Restart Daemon'.\n" + "\n" + "Note that turning off access control will allow anyone logged\n" + "on to this machine to access your screen, which might be\n" + "considered a security problem. Please read the xscreensaver\n" + "manual and FAQ for more information.\n" + "\n" + "You shouldn't run X as root. Instead, you should log in as a\n" + "normal user, and `su' as necessary."); + else + strcat (buf, "Please check your $PATH and permissions."); + + warning_dialog (XtParent (widget), buf, 1); + } +} + + +static int _selected_hack_number = -1; + +static int +selected_hack_number (Widget toplevel) +{ + return _selected_hack_number; +} + + +static int +demo_write_init_file (Widget widget, saver_preferences *p) +{ + if (!write_init_file (XtDisplay (widget), p, short_version, False)) + return 0; + else + { + const char *f = init_file_name(); + if (!f || !*f) + warning_dialog (widget, + "Error:\n\nCouldn't determine init file name!\n", + 100); + else + { + char *b = (char *) malloc (strlen(f) + 1024); + sprintf (b, "Error:\n\nCouldn't write %s\n", f); + warning_dialog (widget, b, 100); + free (b); + } + return -1; + } +} + + +static int +apply_changes_and_save (Widget widget) +{ + prefs_pair *pair = global_prefs_pair; + saver_preferences *p = pair->a; + Widget list_widget = name_to_widget (widget, "list"); + int which = selected_hack_number (widget); + + Widget cmd = name_to_widget (widget, "cmdText"); + Widget enabled = name_to_widget (widget, "enabled"); + + Widget vis = name_to_widget (widget, "combo"); +# ifdef HAVE_XMCOMBOBOX + Widget text = 0; +# else /* !HAVE_XMCOMBOBOX */ + Widget menu = 0, *kids = 0, selected_item = 0; + Cardinal nkids = 0; + int i = 0; +# endif /* !HAVE_XMCOMBOBOX */ + + Bool enabled_p = False; + const char *visual = 0; + const char *command = 0; + + char c; + unsigned long id; + + if (which < 0) return -1; + +# ifdef HAVE_XMCOMBOBOX + XtVaGetValues (vis, XmNtextField, &text, NULL); + if (!text) + /* If we can't get at the text field of this combo box, we're screwed. */ + abort(); + XtVaGetValues (text, XmNvalue, &visual, NULL); + +# else /* !HAVE_XMCOMBOBOX */ + XtVaGetValues (vis, XmNsubMenuId, &menu, NULL); + XtVaGetValues (menu, XmNnumChildren, &nkids, XmNchildren, &kids, NULL); + XtVaGetValues (menu, XmNmenuHistory, &selected_item, NULL); + if (selected_item) + for (i = 0; i < nkids; i++) + if (kids[i] == selected_item) + break; + + visual = visual_menu[i]; +# endif /* !HAVE_XMCOMBOBOX */ + + XtVaGetValues (enabled, XmNset, &enabled_p, NULL); + XtVaGetValues (cmd, XtNvalue, &command, NULL); + + if (maybe_reload_init_file (widget, pair) != 0) + return 1; + + /* Sanity-check and canonicalize whatever the user typed into the combo box. + */ + if (!strcasecmp (visual, "")) visual = ""; + else if (!strcasecmp (visual, "any")) visual = ""; + else if (!strcasecmp (visual, "default")) visual = "Default"; + else if (!strcasecmp (visual, "default-n")) visual = "Default-N"; + else if (!strcasecmp (visual, "default-i")) visual = "Default-I"; + else if (!strcasecmp (visual, "best")) visual = "Best"; + else if (!strcasecmp (visual, "mono")) visual = "Mono"; + else if (!strcasecmp (visual, "monochrome")) visual = "Mono"; + else if (!strcasecmp (visual, "gray")) visual = "Gray"; + else if (!strcasecmp (visual, "grey")) visual = "Gray"; + else if (!strcasecmp (visual, "color")) visual = "Color"; + else if (!strcasecmp (visual, "gl")) visual = "GL"; + else if (!strcasecmp (visual, "staticgray")) visual = "StaticGray"; + else if (!strcasecmp (visual, "staticcolor")) visual = "StaticColor"; + else if (!strcasecmp (visual, "truecolor")) visual = "TrueColor"; + else if (!strcasecmp (visual, "grayscale")) visual = "GrayScale"; + else if (!strcasecmp (visual, "greyscale")) visual = "GrayScale"; + else if (!strcasecmp (visual, "pseudocolor")) visual = "PseudoColor"; + else if (!strcasecmp (visual, "directcolor")) visual = "DirectColor"; + else if (1 == sscanf (visual, " %lu %c", &id, &c)) ; + else if (1 == sscanf (visual, " 0x%lx %c", &id, &c)) ; + else + { + XBell (XtDisplay (widget), 0); /* unparsable */ + visual = ""; + /* #### gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (vis)->entry), "Any");*/ + } + + ensure_selected_item_visible (list_widget); + + if (!p->screenhacks[which]->visual) + p->screenhacks[which]->visual = strdup (""); + if (!p->screenhacks[which]->command) + p->screenhacks[which]->command = strdup (""); + + if (p->screenhacks[which]->enabled_p != enabled_p || + !!strcasecmp (p->screenhacks[which]->visual, visual) || + !!strcasecmp (p->screenhacks[which]->command, command)) + { + /* Something was changed -- store results into the struct, + and write the file. + */ + free (p->screenhacks[which]->visual); + free (p->screenhacks[which]->command); + p->screenhacks[which]->visual = strdup (visual); + p->screenhacks[which]->command = strdup (command); + p->screenhacks[which]->enabled_p = enabled_p; + + return demo_write_init_file (widget, p); + } + + /* No changes made */ + return 0; +} + +void +run_this_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + int which = selected_hack_number (XtParent (button)); + if (which < 0) return; + if (0 == apply_changes_and_save (XtParent (button))) + run_hack (XtParent (button), which, True); +} + + +void +manual_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; + saver_preferences *p = pair->a; + Widget list_widget = name_to_widget (button, "list"); + int which = selected_hack_number (button); + char *name, *name2, *cmd, *s; + if (which < 0) return; + apply_changes_and_save (button); + ensure_selected_item_visible (list_widget); + + name = strdup (p->screenhacks[which]->command); + name2 = name; + while (isspace (*name2)) name2++; + s = name2; + while (*s && !isspace (*s)) s++; + *s = 0; + s = strrchr (name2, '/'); + if (s) name = s+1; + + cmd = get_string_resource (XtDisplay (button), "manualCommand", "ManualCommand"); + if (cmd) + { + char *cmd2 = (char *) malloc (strlen (cmd) + (strlen (name2) * 4) + 100); + strcpy (cmd2, "( "); + sprintf (cmd2 + strlen (cmd2), + cmd, + name2, name2, name2, name2); + strcat (cmd2, " ) &"); + system (cmd2); + free (cmd2); + } + else + { + warning_dialog (XtParent (button), + "Error:\n\nno `manualCommand' resource set.", + 100); + } + + free (name); +} + + +void +run_next_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; + saver_preferences *p = pair->a; + + Widget list_widget = name_to_widget (button, "list"); + int which = selected_hack_number (button); + + button = XtParent (button); + + if (which < 0) + which = 0; + else + which++; + + if (which >= p->screenhacks_count) + which = 0; + + apply_changes_and_save (button); + + XmListDeselectAllItems (list_widget); /* LessTif lossage */ + XmListSelectPos (list_widget, which+1, True); + + ensure_selected_item_visible (list_widget); + populate_demo_window (button, which, pair); + run_hack (button, which, False); +} + + +void +run_prev_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; + saver_preferences *p = pair->a; + + Widget list_widget = name_to_widget (button, "list"); + int which = selected_hack_number (button); + + button = XtParent (button); + + if (which < 0) + which = p->screenhacks_count - 1; + else + which--; + + if (which < 0) + which = p->screenhacks_count - 1; + + apply_changes_and_save (button); + + XmListDeselectAllItems (list_widget); /* LessTif lossage */ + XmListSelectPos (list_widget, which+1, True); + + ensure_selected_item_visible (list_widget); + populate_demo_window (button, which, pair); + run_hack (button, which, False); +} + + +/* Helper for the text fields that contain time specifications: + this parses the text, and does error checking. + */ +static void +hack_time_text (Widget button, const char *line, Time *store, Bool sec_p) +{ + if (*line) + { + int value; + value = parse_time ((char *) line, sec_p, True); + value *= 1000; /* Time measures in microseconds */ + if (value < 0) + { + char b[255]; + sprintf (b, + "Error:\n\n" + "Unparsable time format: \"%s\"\n", + line); + warning_dialog (XtParent (button), b, 100); + } + else + *store = value; + } +} + + +void +prefs_ok_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; + + saver_preferences *p = pair->a; + saver_preferences *p2 = pair->b; + Bool changed = False; + char *v = 0; + + button = XtParent (button); + +# define SECONDS(field, name) \ + v = 0; \ + XtVaGetValues (name_to_widget (button, (name)), XtNvalue, &v, NULL); \ + hack_time_text (button, v, (field), True) + +# define MINUTES(field, name) \ + v = 0; \ + XtVaGetValues (name_to_widget (button, (name)), XtNvalue, &v, NULL); \ + hack_time_text (button, v, (field), False) + +# define INTEGER(field, name) do { \ + unsigned int value; \ + char c; \ + XtVaGetValues (name_to_widget (button, (name)), XtNvalue, &v, NULL); \ + if (! *v) \ + ; \ + else if (sscanf (v, "%u%c", &value, &c) != 1) \ + { \ + char b[255]; \ + sprintf (b, "Error:\n\n" "Not an integer: \"%s\"\n", v); \ + warning_dialog (XtParent (button), b, 100); \ + } \ + else \ + *(field) = value; \ + } while(0) + +# define CHECKBOX(field, name) \ + XtVaGetValues (name_to_widget (button, (name)), XmNset, &field, NULL) + + MINUTES (&p2->timeout, "timeoutText"); + MINUTES (&p2->cycle, "cycleText"); + SECONDS (&p2->fade_seconds, "fadeSecondsText"); + INTEGER (&p2->fade_ticks, "fadeTicksText"); + MINUTES (&p2->lock_timeout, "lockText"); + SECONDS (&p2->passwd_timeout, "passwdText"); + CHECKBOX (p2->verbose_p, "verboseToggle"); + CHECKBOX (p2->install_cmap_p, "cmapToggle"); + CHECKBOX (p2->fade_p, "fadeToggle"); + CHECKBOX (p2->unfade_p, "unfadeToggle"); + CHECKBOX (p2->lock_p, "lockToggle"); + +# undef SECONDS +# undef MINUTES +# undef INTEGER +# undef CHECKBOX + +# define COPY(field) \ + if (p->field != p2->field) changed = True; \ + p->field = p2->field + + COPY(timeout); + COPY(cycle); + COPY(lock_timeout); + COPY(passwd_timeout); + COPY(fade_seconds); + COPY(fade_ticks); + COPY(verbose_p); + COPY(install_cmap_p); + COPY(fade_p); + COPY(unfade_p); + COPY(lock_p); +# undef COPY + + populate_prefs_page (button, pair); + + if (changed) + demo_write_init_file (button, p); +} + + +void +prefs_cancel_cb (Widget button, XtPointer client_data, XtPointer ignored) +{ + prefs_pair *pair = (prefs_pair *) client_data; + + *pair->b = *pair->a; + populate_prefs_page (XtParent (button), pair); +} + + +static void +list_select_cb (Widget list, XtPointer client_data, XtPointer call_data) +{ + prefs_pair *pair = (prefs_pair *) client_data; + + XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data; + int which = lcb->item_position - 1; + + apply_changes_and_save (list); + populate_demo_window (list, which, pair); + + if (lcb->reason == XmCR_DEFAULT_ACTION && which >= 0) + run_hack (list, which, True); +} + + +/* Populating the various widgets + */ + + +/* Formats a `Time' into "H:MM:SS". (Time is microseconds.) + */ +static void +format_time (char *buf, Time time) +{ + int s = time / 1000; + unsigned int h = 0, m = 0; + if (s >= 60) + { + m += (s / 60); + s %= 60; + } + if (m >= 60) + { + h += (m / 60); + m %= 60; + } + sprintf (buf, "%u:%02u:%02u", h, m, s); +} + + +/* Finds the number of the last hack to run, and makes that item be + selected by default. + */ +static void +scroll_to_current_hack (Widget toplevel, prefs_pair *pair) +{ + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *data = 0; + Display *dpy = XtDisplay (toplevel); + int which = 0; + Widget list; + + if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */ + XA_SCREENSAVER_STATUS, + 0, 3, False, XA_INTEGER, + &type, &format, &nitems, &bytesafter, + &data) + == Success + && type == XA_INTEGER + && nitems >= 3 + && data) + which = (int) data[2] - 1; + + if (data) free (data); + + if (which < 0) + return; + + list = name_to_widget (toplevel, "list"); + apply_changes_and_save (toplevel); + + XmListDeselectAllItems (list); /* LessTif lossage */ + XmListSelectPos (list, which+1, True); + + ensure_selected_item_visible (list); + populate_demo_window (toplevel, which, pair); +} + + + +static void +populate_hack_list (Widget toplevel, prefs_pair *pair) +{ + saver_preferences *p = pair->a; + Widget list = name_to_widget (toplevel, "list"); + screenhack **hacks = p->screenhacks; + screenhack **h; + + for (h = hacks; *h; h++) + { + char *pretty_name = (h[0]->name + ? strdup (h[0]->name) + : make_hack_name (XtDisplay (toplevel), h[0]->command)); + + XmString xmstr = XmStringCreate (pretty_name, XmSTRING_DEFAULT_CHARSET); + XmListAddItem (list, xmstr, 0); + XmStringFree (xmstr); + } + + XtAddCallback (list, XmNbrowseSelectionCallback, list_select_cb, pair); + XtAddCallback (list, XmNdefaultActionCallback, list_select_cb, pair); +} + + +static void +populate_prefs_page (Widget top, prefs_pair *pair) +{ + saver_preferences *p = pair->a; + char s[100]; + + format_time (s, p->timeout); + XtVaSetValues (name_to_widget (top, "timeoutText"), XmNvalue, s, NULL); + format_time (s, p->cycle); + XtVaSetValues (name_to_widget (top, "cycleText"), XmNvalue, s, NULL); + format_time (s, p->lock_timeout); + XtVaSetValues (name_to_widget (top, "lockText"), XmNvalue, s, NULL); + format_time (s, p->passwd_timeout); + XtVaSetValues (name_to_widget (top, "passwdText"), XmNvalue, s, NULL); + format_time (s, p->fade_seconds); + XtVaSetValues (name_to_widget (top, "fadeSecondsText"), XmNvalue, s, NULL); + sprintf (s, "%u", p->fade_ticks); + XtVaSetValues (name_to_widget (top, "fadeTicksText"), XmNvalue, s, NULL); + + XtVaSetValues (name_to_widget (top, "verboseToggle"), + XmNset, p->verbose_p, NULL); + XtVaSetValues (name_to_widget (top, "cmapToggle"), + XmNset, p->install_cmap_p, NULL); + XtVaSetValues (name_to_widget (top, "fadeToggle"), + XmNset, p->fade_p, NULL); + XtVaSetValues (name_to_widget (top, "unfadeToggle"), + XmNset, p->unfade_p, NULL); + XtVaSetValues (name_to_widget (top, "lockToggle"), + XmNset, p->lock_p, NULL); + + + { + Bool found_any_writable_cells = False; + Display *dpy = XtDisplay (top); + int nscreens = ScreenCount(dpy); + int i; + for (i = 0; i < nscreens; i++) + { + Screen *s = ScreenOfDisplay (dpy, i); + if (has_writable_cells (s, DefaultVisualOfScreen (s))) + { + found_any_writable_cells = True; + break; + } + } + +#ifdef HAVE_XF86VMODE_GAMMA + found_any_writable_cells = True; /* if we can gamma fade, go for it */ +#endif + + XtVaSetValues (name_to_widget (top, "fadeSecondsLabel"), XtNsensitive, + found_any_writable_cells, NULL); + XtVaSetValues (name_to_widget (top, "fadeTicksLabel"), XtNsensitive, + found_any_writable_cells, NULL); + XtVaSetValues (name_to_widget (top, "fadeSecondsText"), XtNsensitive, + found_any_writable_cells, NULL); + XtVaSetValues (name_to_widget (top, "fadeTicksText"), XtNsensitive, + found_any_writable_cells, NULL); + XtVaSetValues (name_to_widget (top, "cmapToggle"), XtNsensitive, + found_any_writable_cells, NULL); + XtVaSetValues (name_to_widget (top, "fadeToggle"), XtNsensitive, + found_any_writable_cells, NULL); + XtVaSetValues (name_to_widget (top, "unfadeToggle"), XtNsensitive, + found_any_writable_cells, NULL); + } +} + + +static void +sensitize_demo_widgets (Widget toplevel, Bool sensitive_p) +{ + const char *names[] = { "cmdLabel", "cmdText", "enabled", + "visLabel", "combo", "demo", "man" }; + int i; + for (i = 0; i < sizeof(names)/countof(*names); i++) + { + Widget w = name_to_widget (toplevel, names[i]); + XtVaSetValues (w, XtNsensitive, sensitive_p, NULL); + } + + /* I don't know how to handle these yet... */ + { + const char *names2[] = { "cut", "copy", "paste" }; + for (i = 0; i < sizeof(names2)/countof(*names2); i++) + { + Widget w = name_to_widget (toplevel, names2[i]); + XtVaSetValues (w, XtNsensitive, FALSE, NULL); + } + } +} + + + +/* Pixmaps for the up and down arrow buttons (yeah, this is sleazy...) + */ + +#ifdef HAVE_XPM + +static char *up_arrow_xpm[] = { + "15 15 4 1", + " c None s background", + "- c #FFFFFF", + "+ c #D6D6D6", + "@ c #000000", + + " @ ", + " @ ", + " -+@ ", + " -+@ ", + " -+++@ ", + " -+++@ ", + " -+++++@ ", + " -+++++@ ", + " -+++++++@ ", + " -+++++++@ ", + " -+++++++++@ ", + " -+++++++++@ ", + " -+++++++++++@ ", + " @@@@@@@@@@@@@ ", + " " +}; + +static char *down_arrow_xpm[] = { + "15 15 4 1", + " c None s background", + "- c #FFFFFF", + "+ c #D6D6D6", + "@ c #000000", + + " ", + " ------------- ", + " -+++++++++++@ ", + " -+++++++++@ ", + " -+++++++++@ ", + " -+++++++@ ", + " -+++++++@ ", + " -+++++@ ", + " -+++++@ ", + " -+++@ ", + " -+++@ ", + " -+@ ", + " -+@ ", + " @ ", + " @ " +}; + +#endif /* HAVE_XPM */ + + +static void +pixmapify_buttons (Widget toplevel) +{ +#ifdef HAVE_XPM + + Display *dpy = XtDisplay (toplevel); + Window window = XtWindow (toplevel); + XWindowAttributes xgwa; + XpmAttributes xpmattrs; + Pixmap up_pixmap = 0, down_pixmap = 0; + int result; + Widget up = name_to_widget (toplevel, "up"); + Widget dn = name_to_widget (toplevel, "down"); +# ifdef XpmColorSymbols + XColor xc; + XpmColorSymbol symbols[2]; + char color[20]; +# endif + + XGetWindowAttributes (dpy, window, &xgwa); + + xpmattrs.valuemask = 0; + +# ifdef XpmColorSymbols + symbols[0].name = "background"; + symbols[0].pixel = 0; + symbols[1].name = 0; + XtVaGetValues (up, XmNbackground, &xc, NULL); + XQueryColor (dpy, xgwa.colormap, &xc); + sprintf (color, "#%04X%04X%04X", xc.red, xc.green, xc.blue); + symbols[0].value = color; + symbols[0].pixel = xc.pixel; + + xpmattrs.valuemask |= XpmColorSymbols; + xpmattrs.colorsymbols = symbols; + xpmattrs.numsymbols = 1; +# endif + +# ifdef XpmCloseness + xpmattrs.valuemask |= XpmCloseness; + xpmattrs.closeness = 40000; +# endif +# ifdef XpmVisual + xpmattrs.valuemask |= XpmVisual; + xpmattrs.visual = xgwa.visual; +# endif +# ifdef XpmDepth + xpmattrs.valuemask |= XpmDepth; + xpmattrs.depth = xgwa.depth; +# endif +# ifdef XpmColormap + xpmattrs.valuemask |= XpmColormap; + xpmattrs.colormap = xgwa.colormap; +# endif + + result = XpmCreatePixmapFromData(dpy, window, up_arrow_xpm, + &up_pixmap, 0 /* mask */, &xpmattrs); + if (!up_pixmap || (result != XpmSuccess && result != XpmColorError)) + { + fprintf (stderr, "%s: Can't load pixmaps\n", progname); + return; + } + + result = XpmCreatePixmapFromData(dpy, window, down_arrow_xpm, + &down_pixmap, 0 /* mask */, &xpmattrs); + if (!down_pixmap || (result != XpmSuccess && result != XpmColorError)) + { + fprintf (stderr, "%s: Can't load pixmaps\n", progname); + return; + } + + XtVaSetValues (up, XmNlabelType, XmPIXMAP, XmNlabelPixmap, up_pixmap, NULL); + XtVaSetValues (dn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, down_pixmap,NULL); + +#endif /* HAVE_XPM */ +} + + + +char * +get_hack_blurb (Display *dpy, screenhack *hack) +{ + char *doc_string; + char *prog_name = strdup (hack->command); + char *pretty_name = (hack->name + ? strdup (hack->name) + : make_hack_name (dpy, hack->command)); + char doc_name[255], doc_class[255]; + char *s, *s2; + + for (s = prog_name; *s && !isspace(*s); s++) + ; + *s = 0; + s = strrchr (prog_name, '/'); + if (s) strcpy (prog_name, s+1); + + sprintf (doc_name, "hacks.%s.documentation", pretty_name); + sprintf (doc_class, "hacks.%s.documentation", prog_name); + free (prog_name); + free (pretty_name); + + doc_string = get_string_resource (dpy, doc_name, doc_class); + if (doc_string) + { + for (s = doc_string; *s; s++) + { + if (*s == '\n') + { + /* skip over whitespace at beginning of line */ + s++; + while (*s && (*s == ' ' || *s == '\t')) + s++; + } + else if (*s == ' ' || *s == '\t') + { + /* compress all other horizontal whitespace. */ + *s = ' '; + s++; + for (s2 = s; *s2 && (*s2 == ' ' || *s2 == '\t'); s2++) + ; + if (s2 > s) strcpy (s, s2); + s--; + } + } + + while (*s && isspace (*s)) /* Strip trailing whitespace */ + *(--s) = 0; + + /* Delete whitespace at end of each line. */ + for (; s > doc_string; s--) + if (*s == '\n' && (s[-1] == ' ' || s[-1] == '\t')) + { + for (s2 = s-1; + s2 > doc_string && (*s2 == ' ' || *s2 == '\t'); + s2--) + ; + s2++; + if (s2 < s) strcpy (s2, s); + s = s2; + } + + /* Delete leading blank lines. */ + for (s = doc_string; *s == '\n'; s++) + ; + if (s > doc_string) strcpy (doc_string, s); + } + else + { +# if 0 + static int doc_installed = 0; + if (doc_installed == 0) + { + if (get_boolean_resource ("hacks.documentation.isInstalled", + "hacks.documentation.isInstalled")) + doc_installed = 1; + else + doc_installed = -1; + } + + if (doc_installed < 0) + doc_string = + strdup ("Error:\n\n" + "The documentation strings do not appear to be " + "installed. This is probably because there is " + "an \"XScreenSaver\" app-defaults file installed " + "that is from an older version of the program. " + "To fix this problem, delete that file, or " + "install a current version (either will work.)"); + else +# endif /* 0 */ + doc_string = strdup ( + "\n" + "This is the Motif version of \"xscreensaver-demo\". The Motif " + "version is no longer maintained. Please use the GTK version " + "instead, which has many more features." + "\n\n" + "If you were running the GTK version, there would be a preview " + "of this screen saver mode displayed here, along with graphical " + "configuration options."); + } + + return doc_string; +} + + +static void +populate_demo_window (Widget toplevel, int which, prefs_pair *pair) +{ + saver_preferences *p = pair->a; + screenhack *hack = (which >= 0 ? p->screenhacks[which] : 0); + Widget frameL = name_to_widget (toplevel, "frameLabel"); + Widget doc = name_to_widget (toplevel, "doc"); + Widget cmd = name_to_widget (toplevel, "cmdText"); + Widget enabled = name_to_widget (toplevel, "enabled"); + Widget vis = name_to_widget (toplevel, "combo"); + int i = 0; + + char *pretty_name = (hack + ? (hack->name + ? strdup (hack->name) + : make_hack_name (XtDisplay (toplevel), hack->command)) + : 0); + char *doc_string = hack ? get_hack_blurb (XtDisplay (toplevel), hack) : 0; + + XmString xmstr; + + xmstr = XmStringCreate (pretty_name, XmSTRING_DEFAULT_CHARSET); + XtVaSetValues (frameL, XmNlabelString, xmstr, NULL); + XmStringFree (xmstr); + + XtVaSetValues (doc, XmNvalue, doc_string, NULL); + XtVaSetValues (cmd, XmNvalue, (hack ? hack->command : ""), NULL); + + XtVaSetValues (enabled, XmNset, (hack ? hack->enabled_p : False), NULL); + + i = 0; + if (hack && hack->visual && *hack->visual) + for (i = 0; visual_menu[i]; i++) + if (!strcasecmp (hack->visual, visual_menu[i])) + break; + if (!visual_menu[i]) i = -1; + + { +# ifdef HAVE_XMCOMBOBOX + Widget text = 0; + XtVaGetValues (vis, XmNtextField, &text, NULL); + XtVaSetValues (vis, XmNselectedPosition, i, NULL); + if (i < 0) + XtVaSetValues (text, XmNvalue, hack->visual, NULL); +# else /* !HAVE_XMCOMBOBOX */ + Cardinal nkids; + Widget *kids; + Widget menu; + + XtVaGetValues (vis, XmNsubMenuId, &menu, NULL); + if (!menu) abort (); + XtVaGetValues (menu, XmNnumChildren, &nkids, XmNchildren, &kids, NULL); + if (!kids) abort(); + if (i < nkids) + XtVaSetValues (vis, XmNmenuHistory, kids[i], NULL); +# endif /* !HAVE_XMCOMBOBOX */ + } + + sensitize_demo_widgets (toplevel, (hack ? True : False)); + + if (pretty_name) free (pretty_name); + if (doc_string) free (doc_string); + + _selected_hack_number = which; +} + + + +static int +maybe_reload_init_file (Widget widget, prefs_pair *pair) +{ + int status = 0; + saver_preferences *p = pair->a; + + static Bool reentrant_lock = False; + if (reentrant_lock) return 0; + reentrant_lock = True; + + if (init_file_changed_p (p)) + { + const char *f = init_file_name(); + char *b; + int which; + Widget list; + + if (!f || !*f) return 0; + b = (char *) malloc (strlen(f) + 1024); + sprintf (b, + "Warning:\n\n" + "file \"%s\" has changed, reloading.\n", + f); + warning_dialog (widget, b, 100); + free (b); + + load_init_file (XtDisplay (widget), p); + + which = selected_hack_number (widget); + list = name_to_widget (widget, "list"); + + XtVaSetValues (list, XmNitemCount, 0, NULL); + + populate_hack_list (widget, pair); + + XmListDeselectAllItems (list); /* LessTif lossage */ + XmListSelectPos (list, which+1, True); + + populate_prefs_page (widget, pair); + populate_demo_window (widget, which, pair); + ensure_selected_item_visible (list); + + status = 1; + } + + reentrant_lock = False; + return status; +} + + + +/* Attach all callback functions to widgets + */ + +static void +add_callbacks (Widget toplevel, prefs_pair *pair) +{ + Widget w; + +# define CB(NAME,FN) \ + w = name_to_widget (toplevel, (NAME)); \ + XtAddCallback (w, XmNactivateCallback, (FN), pair) + + CB ("blank", activate_menu_cb); + CB ("lock", lock_menu_cb); + CB ("kill", kill_menu_cb); + CB ("restart", restart_menu_cb); + CB ("exit", exit_menu_cb); + + CB ("cut", cut_menu_cb); + CB ("copy", copy_menu_cb); + CB ("paste", paste_menu_cb); + + CB ("about", about_menu_cb); + CB ("docMenu", doc_menu_cb); + + CB ("down", run_next_cb); + CB ("up", run_prev_cb); + CB ("demo", run_this_cb); + CB ("man", manual_cb); + + CB ("preferencesForm.Cancel", prefs_cancel_cb); + CB ("preferencesForm.OK", prefs_ok_cb); + +# undef CB +} + + +static void +sanity_check_resources (Widget toplevel) +{ + const char *names[] = { "demoTab", "optionsTab", "cmdLabel", "visLabel", + "enabled", "demo", "man", "timeoutLabel", + "cycleLabel", "fadeSecondsLabel", "fadeTicksLabel", + "lockLabel", "passwdLabel" }; + int i; + for (i = 0; i < sizeof(names)/countof(*names); i++) + { + Widget w = name_to_widget (toplevel, names[i]); + const char *name = XtName(w); + XmString xm = 0; + char *label = 0; + XtVaGetValues (w, XmNlabelString, &xm, NULL); + if (xm) XmStringGetLtoR (xm, XmSTRING_DEFAULT_CHARSET, &label); + if (w && (!label || !strcmp (name, label))) + { + xm = XmStringCreate ("ERROR", XmSTRING_DEFAULT_CHARSET); + XtVaSetValues (w, XmNlabelString, xm, NULL); + } + } +} + +/* Set certain buttons to be the same size (the max of the set.) + */ +static void +hack_button_sizes (Widget toplevel) +{ + Widget demo = name_to_widget (toplevel, "demo"); + Widget man = name_to_widget (toplevel, "man"); + Widget ok = name_to_widget (toplevel, "OK"); + Widget can = name_to_widget (toplevel, "Cancel"); + Widget up = name_to_widget (toplevel, "up"); + Widget down = name_to_widget (toplevel, "down"); + Dimension w1, w2; + + XtVaGetValues (demo, XmNwidth, &w1, NULL); + XtVaGetValues (man, XmNwidth, &w2, NULL); + XtVaSetValues ((w1 > w2 ? man : demo), XmNwidth, (w1 > w2 ? w1 : w2), NULL); + + XtVaGetValues (ok, XmNwidth, &w1, NULL); + XtVaGetValues (can, XmNwidth, &w2, NULL); + XtVaSetValues ((w1 > w2 ? can : ok), XmNwidth, (w1 > w2 ? w1 : w2), NULL); + + XtVaGetValues (up, XmNwidth, &w1, NULL); + XtVaGetValues (down, XmNwidth, &w2, NULL); + XtVaSetValues ((w1 > w2 ? down : up), XmNwidth, (w1 > w2 ? w1 : w2), NULL); +} + + + + +/* The main demo-mode command loop. + */ + +#if 0 +static Bool +mapper (XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks, + XrmRepresentation *type, XrmValue *value, XPointer closure) +{ + int i; + for (i = 0; quarks[i]; i++) + { + if (bindings[i] == XrmBindTightly) + fprintf (stderr, (i == 0 ? "" : ".")); + else if (bindings[i] == XrmBindLoosely) + fprintf (stderr, "*"); + else + fprintf (stderr, " ??? "); + fprintf(stderr, "%s", XrmQuarkToString (quarks[i])); + } + + fprintf (stderr, ": %s\n", (char *) value->addr); + + return False; +} +#endif + + +static void +the_network_is_not_the_computer (Widget parent) +{ + Display *dpy = XtDisplay (parent); + char *rversion, *ruser, *rhost; + char *luser, *lhost; + char *msg = 0; + struct passwd *p = getpwuid (getuid ()); + const char *d = DisplayString (dpy); + +# if defined(HAVE_UNAME) + struct utsname uts; + if (uname (&uts) < 0) + lhost = ""; + else + lhost = uts.nodename; +# elif defined(VMS) + strcpy (lhost, getenv("SYS$NODE")); +# else /* !HAVE_UNAME && !VMS */ + strcat (lhost, ""); +# endif /* !HAVE_UNAME && !VMS */ + + if (p && p->pw_name) + luser = p->pw_name; + else + luser = "???"; + + server_xscreensaver_version (dpy, &rversion, &ruser, &rhost); + + /* Make a buffer that's big enough for a number of copies of all the + strings, plus some. */ + msg = (char *) malloc (10 * ((rversion ? strlen(rversion) : 0) + + (ruser ? strlen(ruser) : 0) + + (rhost ? strlen(rhost) : 0) + + strlen(lhost) + + strlen(luser) + + strlen(d) + + 1024)); + *msg = 0; + + if (!rversion || !*rversion) + { + sprintf (msg, + "Warning:\n\n" + "The XScreenSaver daemon doesn't seem to be running\n" + "on display \"%s\". You can launch it by selecting\n" + "`Restart Daemon' from the File menu, or by typing\n" + "\"xscreensaver &\" in a shell.", + d); + } + else if (p && ruser && *ruser && !!strcmp (ruser, p->pw_name)) + { + /* Warn that the two processes are running as different users. + */ + sprintf(msg, + "Warning:\n\n" + "%s is running as user \"%s\" on host \"%s\".\n" + "But the xscreensaver managing display \"%s\"\n" + "is running as user \"%s\" on host \"%s\".\n" + "\n" + "Since they are different users, they won't be reading/writing\n" + "the same ~/.xscreensaver file, so %s isn't\n" + "going to work right.\n" + "\n" + "Either re-run %s as \"%s\", or re-run\n" + "xscreensaver as \"%s\" (which you can do by\n" + "selecting `Restart Daemon' from the File menu.)\n", + progname, luser, lhost, + d, + (ruser ? ruser : "???"), (rhost ? rhost : "???"), + progname, + progname, (ruser ? ruser : "???"), + luser); + } + else if (rhost && *rhost && !!strcmp (rhost, lhost)) + { + /* Warn that the two processes are running on different hosts. + */ + sprintf (msg, + "Warning:\n\n" + "%s is running as user \"%s\" on host \"%s\".\n" + "But the xscreensaver managing display \"%s\"\n" + "is running as user \"%s\" on host \"%s\".\n" + "\n" + "If those two machines don't share a file system (that is,\n" + "if they don't see the same ~%s/.xscreensaver file) then\n" + "%s won't work right.\n" + "\n" + "You can restart the daemon on \"%s\" as \"%s\" by\n" + "selecting `Restart Daemon' from the File menu.)", + progname, luser, lhost, + d, + (ruser ? ruser : "???"), (rhost ? rhost : "???"), + luser, + progname, + lhost, luser); + } + else if (!!strcmp (rversion, short_version)) + { + /* Warn that the version numbers don't match. + */ + sprintf (msg, + "Warning:\n\n" + "This is %s version %s.\n" + "But the xscreensaver managing display \"%s\"\n" + "is version %s. This could cause problems.", + progname, short_version, + d, + rversion); + } + + + if (*msg) + warning_dialog (parent, msg, 1); + + free (msg); +} + + +/* We use this error handler so that X errors are preceeded by the name + of the program that generated them. + */ +static int +demo_ehandler (Display *dpy, XErrorEvent *error) +{ + fprintf (stderr, "\nX error in %s:\n", progname); + XmuPrintDefaultErrorMessage (dpy, error, stderr); + exit (-1); + return 0; +} + + + +#ifdef __GNUC__ + __extension__ /* shut up about "string length is greater than the length + ISO C89 compilers are required to support" when including + the .ad file... */ +#endif + +static char *defaults[] = { +#include "XScreenSaver_ad.h" +#include "XScreenSaver_Xm_ad.h" + 0 +}; + + +int +main (int argc, char **argv) +{ + XtAppContext app; + prefs_pair Pair, *pair; + saver_preferences P, P2, *p, *p2; + Bool prefs = False; + int i; + Display *dpy; + Widget toplevel_shell, dialog; + char *real_progname = argv[0]; + char *s; + + s = strrchr (real_progname, '/'); + if (s) real_progname = s+1; + + p = &P; + p2 = &P2; + pair = &Pair; + pair->a = p; + pair->b = p2; + memset (p, 0, sizeof (*p)); + memset (p2, 0, sizeof (*p2)); + + global_prefs_pair = pair; + + progname = real_progname; + + /* We must read exactly the same resources as xscreensaver. + That means we must have both the same progclass *and* progname, + at least as far as the resource database is concerned. So, + put "xscreensaver" in argv[0] while initializing Xt. + */ + argv[0] = "xscreensaver"; + progname = argv[0]; + + + toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, &argc, argv, + defaults, 0, 0); + + dpy = XtDisplay (toplevel_shell); + db = XtDatabase (dpy); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + XSetErrorHandler (demo_ehandler); + + /* Complain about unrecognized command-line arguments. + */ + for (i = 1; i < argc; i++) + { + char *s = argv[i]; + if (s[0] == '-' && s[1] == '-') + s++; + if (!strcmp (s, "-prefs")) + prefs = True; + else + { + fprintf (stderr, "usage: %s [ -display dpy-string ] [ -prefs ]\n", + real_progname); + exit (1); + } + } + + short_version = (char *) malloc (5); + memcpy (short_version, screensaver_id + 17, 4); + short_version [4] = 0; + + /* Load the init file, which may end up consulting the X resource database + and the site-wide app-defaults file. Note that at this point, it's + important that `progname' be "xscreensaver", rather than whatever + was in argv[0]. + */ + p->db = db; + load_init_file (dpy, p); + *p2 = *p; + + /* Now that Xt has been initialized, and the resources have been read, + we can set our `progname' variable to something more in line with + reality. + */ + progname = real_progname; + + +#if 0 + { + XrmName name = { 0 }; + XrmClass class = { 0 }; + int count = 0; + XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper, + (POINTER) &count); + } +#endif + + + /* Intern the atoms that xscreensaver_command() needs. + */ + XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False); + XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False); + XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False); + XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False); + XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False); + XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False); + XA_SELECT = XInternAtom (dpy, "SELECT", False); + XA_DEMO = XInternAtom (dpy, "DEMO", False); + XA_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False); + XA_BLANK = XInternAtom (dpy, "BLANK", False); + XA_LOCK = XInternAtom (dpy, "LOCK", False); + XA_EXIT = XInternAtom (dpy, "EXIT", False); + XA_RESTART = XInternAtom (dpy, "RESTART", False); + + /* Create the window and all its widgets. + */ + dialog = create_xscreensaver_demo (toplevel_shell); + + /* Set the window's title. */ + { + char title[255]; + char *v = (char *) strdup(strchr(screensaver_id, ' ')); + char *s1, *s2, *s3, *s4; + s1 = (char *) strchr(v, ' '); s1++; + s2 = (char *) strchr(s1, ' '); + s3 = (char *) strchr(v, '('); s3++; + s4 = (char *) strchr(s3, ')'); + *s2 = 0; + *s4 = 0; + sprintf (title, "%.50s %.50s, %.50s", progclass, s1, s3); + XtVaSetValues (toplevel_shell, XtNtitle, title, NULL); + free (v); + } + + sanity_check_resources (toplevel_shell); + add_callbacks (toplevel_shell, pair); + populate_hack_list (toplevel_shell, pair); + populate_prefs_page (toplevel_shell, pair); + sensitize_demo_widgets (toplevel_shell, False); + scroll_to_current_hack (toplevel_shell, pair); + + XtManageChild (dialog); + XtRealizeWidget(toplevel_shell); + + /* The next few calls must come after XtRealizeWidget(). */ + pixmapify_buttons (toplevel_shell); + hack_button_sizes (toplevel_shell); + ensure_selected_item_visible (name_to_widget (toplevel_shell, "list")); + + XSync (dpy, False); + XtVaSetValues (toplevel_shell, XmNallowShellResize, False, NULL); + + + /* Handle the -prefs command-line argument. */ + if (prefs) + { + Widget tabber = name_to_widget (toplevel_shell, "folder"); + Widget this_tab = name_to_widget (toplevel_shell, "optionsTab"); + Widget this_page = name_to_widget (toplevel_shell, "preferencesForm"); + Widget *kids = 0; + Cardinal nkids = 0; + if (!tabber) abort(); + + XtVaGetValues (tabber, XmNnumChildren, &nkids, XmNchildren, &kids, NULL); + if (!kids) abort(); + if (nkids > 0) + XtUnmanageChildren (kids, nkids); + + XtManageChild (this_page); + + XmProcessTraversal (this_tab, XmTRAVERSE_CURRENT); + } + + /* Issue any warnings about the running xscreensaver daemon. */ + the_network_is_not_the_computer (toplevel_shell); + + + XtAppMainLoop (app); + exit (0); +} + +#endif /* HAVE_MOTIF -- whole file */ diff --git a/driver/dpms.c b/driver/dpms.c new file mode 100644 index 00000000..d88737ee --- /dev/null +++ b/driver/dpms.c @@ -0,0 +1,296 @@ +/* dpms.c --- syncing the X Display Power Management values + * xscreensaver, Copyright (c) 2001-2011 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. + */ + +/* Display Power Management System (DPMS.) + + On XFree86 systems, "man xset" reports: + + -dpms The -dpms option disables DPMS (Energy Star) features. + +dpms The +dpms option enables DPMS (Energy Star) features. + + dpms flags... + The dpms option allows the DPMS (Energy Star) + parameters to be set. The option can take up to three + numerical values, or the `force' flag followed by a + DPMS state. The `force' flags forces the server to + immediately switch to the DPMS state specified. The + DPMS state can be one of `standby', `suspend', or + `off'. When numerical values are given, they set the + inactivity period before the three modes are activated. + The first value given is for the `standby' mode, the + second is for the `suspend' mode, and the third is for + the `off' mode. Setting these values implicitly + enables the DPMS features. A value of zero disables a + particular mode. + + However, note that the implementation is more than a little bogus, + in that there is code in /usr/X11R6/lib/libXdpms.a to implement all + the usual server-extension-querying utilities -- but there are no + prototypes in any header file! Thus, the prototypes here. (The + stuff in X11/extensions/dpms.h and X11/extensions/dpmsstr.h define + the raw X protcol, they don't define the API to libXdpms.a.) + + Some documentation: + Library: ftp://ftp.x.org/pub/R6.4/xc/doc/specs/Xext/DPMSLib.ms + Protocol: ftp://ftp.x.org/pub/R6.4/xc/doc/specs/Xext/DPMS.ms + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#ifdef HAVE_DPMS_EXTENSION /* almost the whole file */ + +# include +# include +/*# include */ + + /* Why this crap is not in a header file somewhere, I have no idea. Losers! + */ + extern Bool DPMSQueryExtension (Display *, int *event_ret, int *err_ret); + extern Status DPMSGetVersion (Display *, int *major_ret, int *minor_ret); + extern Bool DPMSCapable (Display *); + extern Status DPMSInfo (Display *, CARD16 *power_level, BOOL *state); + extern Status DPMSEnable (Display *dpy); + extern Status DPMSDisable (Display *dpy); + extern Status DPMSForceLevel (Display *, CARD16 level); + extern Status DPMSSetTimeouts (Display *, CARD16 standby, CARD16 suspend, + CARD16 off); + extern Bool DPMSGetTimeouts (Display *, CARD16 *standby, + CARD16 *suspend, CARD16 *off); + +#endif /* HAVE_DPMS_EXTENSION */ + + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" + +#ifdef HAVE_DPMS_EXTENSION + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + + +void +sync_server_dpms_settings (Display *dpy, Bool enabled_p, + int standby_secs, int suspend_secs, int off_secs, + Bool verbose_p) +{ + int event = 0, error = 0; + BOOL o_enabled = False; + CARD16 o_power = 0; + CARD16 o_standby = 0, o_suspend = 0, o_off = 0; + Bool bogus_p = False; + + if (standby_secs == 0 && suspend_secs == 0 && off_secs == 0) + /* all zero implies "DPMS disabled" */ + enabled_p = False; + + else if ((standby_secs != 0 && standby_secs < 10) || + (suspend_secs != 0 && suspend_secs < 10) || + (off_secs != 0 && off_secs < 10)) + /* any negative, or any positive-and-less-than-10-seconds, is crazy. */ + bogus_p = True; + + if (bogus_p) enabled_p = False; + + /* X protocol sends these values in a CARD16, so truncate them to 16 bits. + This means that the maximum timeout is 18:12:15. + */ + if (standby_secs > 0xFFFF) standby_secs = 0xFFFF; + if (suspend_secs > 0xFFFF) suspend_secs = 0xFFFF; + if (off_secs > 0xFFFF) off_secs = 0xFFFF; + + if (! DPMSQueryExtension (dpy, &event, &error)) + { + if (verbose_p) + fprintf (stderr, "%s: XDPMS extension not supported.\n", blurb()); + return; + } + + if (! DPMSCapable (dpy)) + { + if (verbose_p) + fprintf (stderr, "%s: DPMS not supported.\n", blurb()); + return; + } + + if (! DPMSInfo (dpy, &o_power, &o_enabled)) + { + if (verbose_p) + fprintf (stderr, "%s: unable to get DPMS state.\n", blurb()); + return; + } + + if (o_enabled != enabled_p) + { + if (! (enabled_p ? DPMSEnable (dpy) : DPMSDisable (dpy))) + { + if (verbose_p) + fprintf (stderr, "%s: unable to set DPMS state.\n", blurb()); + return; + } + else if (verbose_p) + fprintf (stderr, "%s: turned DPMS %s.\n", blurb(), + enabled_p ? "on" : "off"); + } + + if (bogus_p) + { + if (verbose_p) + fprintf (stderr, "%s: not setting bogus DPMS timeouts: %d %d %d.\n", + blurb(), standby_secs, suspend_secs, off_secs); + return; + } + + if (!DPMSGetTimeouts (dpy, &o_standby, &o_suspend, &o_off)) + { + if (verbose_p) + fprintf (stderr, "%s: unable to get DPMS timeouts.\n", blurb()); + return; + } + + if (o_standby != standby_secs || + o_suspend != suspend_secs || + o_off != off_secs) + { + if (!DPMSSetTimeouts (dpy, standby_secs, suspend_secs, off_secs)) + { + if (verbose_p) + fprintf (stderr, "%s: unable to set DPMS timeouts.\n", blurb()); + return; + } + else if (verbose_p) + fprintf (stderr, "%s: set DPMS timeouts: %d %d %d.\n", blurb(), + standby_secs, suspend_secs, off_secs); + } +} + +Bool +monitor_powered_on_p (saver_info *si) +{ + Bool result; + int event_number, error_number; + BOOL onoff = False; + CARD16 state; + + if (!DPMSQueryExtension(si->dpy, &event_number, &error_number)) + /* Server doesn't know -- assume the monitor is on. */ + result = True; + + else if (!DPMSCapable(si->dpy)) + /* Server says the monitor doesn't do power management -- so it's on. */ + result = True; + + else + { + DPMSInfo(si->dpy, &state, &onoff); + if (!onoff) + /* Server says DPMS is disabled -- so the monitor is on. */ + result = True; + else + switch (state) { + case DPMSModeOn: result = True; break; /* really on */ + case DPMSModeStandby: result = False; break; /* kinda off */ + case DPMSModeSuspend: result = False; break; /* pretty off */ + case DPMSModeOff: result = False; break; /* really off */ + default: result = True; break; /* protocol error? */ + } + } + + return result; +} + +void +monitor_power_on (saver_info *si, Bool on_p) +{ + if ((!!on_p) != monitor_powered_on_p (si)) + { + XErrorHandler old_handler; + int event_number, error_number; + if (!DPMSQueryExtension(si->dpy, &event_number, &error_number) || + !DPMSCapable(si->dpy)) + { + if (si->prefs.verbose_p) + fprintf (stderr, + "%s: unable to power %s monitor: no DPMS extension.\n", + blurb(), (on_p ? "on" : "off")); + return; + } + + /* The manual for DPMSForceLevel() says that it throws BadMatch if + "DPMS is disabled on the specified display." + + The manual for DPMSCapable() says that it "returns True if the X + server is capable of DPMS." + + Apparently they consider "capable of DPMS" and "DPMS is enabled" + to be different things, and so even if DPMSCapable() returns + True, DPMSForceLevel() *might* throw an X Error. Isn't that + just fucking special. + */ + XSync (si->dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + XSync (si->dpy, False); + DPMSForceLevel(si->dpy, (on_p ? DPMSModeOn : DPMSModeOff)); + XSync (si->dpy, False); + /* Ignore error_handler_hit_p, just probe monitor instead */ + + if ((!!on_p) != monitor_powered_on_p (si)) /* double-check */ + fprintf (stderr, + "%s: DPMSForceLevel(dpy, %s) did not change monitor power state.\n", + blurb(), + (on_p ? "DPMSModeOn" : "DPMSModeOff")); + } +} + +#else /* !HAVE_DPMS_EXTENSION */ + +void +sync_server_dpms_settings (Display *dpy, Bool enabled_p, + int standby_secs, int suspend_secs, int off_secs, + Bool verbose_p) +{ + if (verbose_p) + fprintf (stderr, "%s: DPMS support not compiled in.\n", blurb()); +} + +Bool +monitor_powered_on_p (saver_info *si) +{ + return True; +} + +void +monitor_power_on (saver_info *si, Bool on_p) +{ + return; +} + +#endif /* !HAVE_DPMS_EXTENSION */ diff --git a/driver/exec.c b/driver/exec.c new file mode 100644 index 00000000..38ca88a0 --- /dev/null +++ b/driver/exec.c @@ -0,0 +1,300 @@ +/* exec.c --- executes a program in *this* pid, without an intervening process. + * xscreensaver, Copyright (c) 1991-2013 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. + */ + + +/* I don't believe what a sorry excuse for an operating system UNIX is! + + - I want to spawn a process. + - I want to know it's pid so that I can kill it. + - I would like to receive a message when it dies of natural causes. + - I want the spawned process to have user-specified arguments. + + If shell metacharacters are present (wildcards, backquotes, etc), the + only way to parse those arguments is to run a shell to do the parsing + for you. + + And the only way to know the pid of the process is to fork() and exec() + it in the spawned side of the fork. + + But if you're running a shell to parse your arguments, this gives you + the pid of the *shell*, not the pid of the *process* that you're + actually interested in, which is an *inferior* of the shell. This also + means that the SIGCHLD you get applies to the shell, not its inferior. + (Why isn't that sufficient? I don't remember any more, but it turns + out that it isn't.) + + So, the only solution, when metacharacters are present, is to force the + shell to exec() its inferior. What a fucking hack! We prepend "exec " + to the command string, and hope it doesn't contain unquoted semicolons + or ampersands (we don't search for them, because we don't want to + prohibit their use in quoted strings (messages, for example) and parsing + out the various quote characters is too much of a pain.) + + (Actually, Clint Wong points out that process groups + might be used to take care of this problem; this may be worth considering + some day, except that, 1: this code works now, so why fix it, and 2: from + what I've seen in Emacs, dealing with process groups isn't especially + portable.) + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include + +#ifndef ESRCH +# include +#endif + +#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) +# include /* for setpriority() and PRIO_PROCESS */ + /* and also setrlimit() and RLIMIT_AS */ +#endif + +#ifdef VMS +# include +# include /* for close */ +# include /* for getpid */ +# define pid_t int +# define fork vfork +#endif /* VMS */ + +#include "exec.h" + +extern const char *blurb (void); + +static void nice_process (int nice_level); + + +#ifndef VMS + +static void +exec_simple_command (const char *command) +{ + char *av[1024]; + int ac = 0; + char *token = strtok (strdup(command), " \t"); + while (token) + { + av[ac++] = token; + token = strtok(0, " \t"); + } + av[ac] = 0; + + execvp (av[0], av); /* shouldn't return. */ +} + + +static void +exec_complex_command (const char *shell, const char *command) +{ + char *av[5]; + int ac = 0; + char *command2 = (char *) malloc (strlen (command) + 10); + const char *s; + int got_eq = 0; + const char *after_vars; + + /* Skip leading whitespace. + */ + while (*command == ' ' || *command == '\t') + command++; + + /* If the string has a series of tokens with "=" in them at them, set + `after_vars' to point into the string after those tokens and any + trailing whitespace. Otherwise, after_vars == command. + */ + after_vars = command; + for (s = command; *s; s++) + { + if (*s == '=') got_eq = 1; + else if (*s == ' ') + { + if (got_eq) + { + while (*s == ' ' || *s == '\t') + s++; + after_vars = s; + got_eq = 0; + } + else + break; + } + } + + *command2 = 0; + strncat (command2, command, after_vars - command); + strcat (command2, "exec "); + strcat (command2, after_vars); + + /* We have now done these transformations: + "foo -x -y" ==> "exec foo -x -y" + "BLAT=foop foo -x" ==> "BLAT=foop exec foo -x" + "BLAT=foop A=b foo -x" ==> "BLAT=foop A=b exec foo -x" + */ + + + /* Invoke the shell as "/bin/sh -c 'exec prog -arg -arg ...'" */ + av [ac++] = (char *) shell; + av [ac++] = "-c"; + av [ac++] = command2; + av [ac] = 0; + + execvp (av[0], av); /* shouldn't return. */ +} + +#else /* VMS */ + +static void +exec_vms_command (const char *command) +{ + system (command); + fflush (stderr); + fflush (stdout); + exit (1); /* Note that this only exits a child fork. */ +} + +#endif /* !VMS */ + + +void +exec_command (const char *shell, const char *command, int nice_level) +{ + int hairy_p; + +#ifndef VMS + nice_process (nice_level); + + hairy_p = !!strpbrk (command, "*?$&!<>[];`'\\\"="); + /* note: = is in the above because of the sh syntax "FOO=bar cmd". */ + + if (getuid() == (uid_t) 0 || geteuid() == (uid_t) 0) + { + /* If you're thinking of commenting this out, think again. + If you do so, you will open a security hole. Mail jwz + so that he may enlighten you as to the error of your ways. + */ + fprintf (stderr, "%s: we're still running as root! Disaster!\n", + blurb()); + exit (-1); + } + + if (hairy_p) + /* If it contains any shell metacharacters, do it the hard way, + and fork a shell to parse the arguments for us. */ + exec_complex_command (shell, command); + else + /* Otherwise, we can just exec the program directly. */ + exec_simple_command (command); + +#else /* VMS */ + exec_vms_command (command); +#endif /* VMS */ +} + + +/* Setting process priority + */ + +static void +nice_process (int nice_level) +{ + if (nice_level == 0) + return; + +#if defined(HAVE_NICE) + { + int old_nice = nice (0); + int n = nice_level - old_nice; + errno = 0; + if (nice (n) == -1 && errno != 0) + { + char buf [512]; + sprintf (buf, "%s: nice(%d) failed", blurb(), n); + perror (buf); + } + } +#elif defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) + if (setpriority (PRIO_PROCESS, getpid(), nice_level) != 0) + { + char buf [512]; + sprintf (buf, "%s: setpriority(PRIO_PROCESS, %lu, %d) failed", + blurb(), (unsigned long) getpid(), nice_level); + perror (buf); + } +#else + fprintf (stderr, + "%s: don't know how to change process priority on this system.\n", + blurb()); + +#endif +} + + +/* Whether the given command exists on $PATH. + (Anything before the first space is considered to be the program name.) + */ +int +on_path_p (const char *program) +{ + int result = 0; + struct stat st; + char *cmd = strdup (program); + char *token = strchr (cmd, ' '); + char *path = 0; + int L; + + if (token) *token = 0; + token = 0; + + if (strchr (cmd, '/')) + { + result = (0 == stat (cmd, &st)); + goto DONE; + } + + path = getenv("PATH"); + if (!path || !*path) + goto DONE; + + L = strlen (cmd); + path = strdup (path); + token = strtok (path, ":"); + + while (token) + { + char *p2 = (char *) malloc (strlen (token) + L + 3); + strcpy (p2, token); + strcat (p2, "/"); + strcat (p2, cmd); + result = (0 == stat (p2, &st)); + free (p2); + if (result) + goto DONE; + token = strtok (0, ":"); + } + + DONE: + free (cmd); + if (path) free (path); + return result; +} + 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/link_axp.com b/driver/link_axp.com new file mode 100644 index 00000000..a1418927 --- /dev/null +++ b/driver/link_axp.com @@ -0,0 +1,15 @@ +$! We fisrt test the version of DECW/Motif ; if 1.2 we need to link with new +$! X11R5 libraries +$@sys$update:decw$get_image_version sys$share:decw$xlibshr.exe decw$version +$ if f$extract(4,3,decw$version).eqs."1.2" +$ then +$! DECW/Motif 1.2 : link with X11R5 libraries +$ link xscreensaver-command,vms_axp_12.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_axp_12.opt/opt +$ else +$! Else, link with X11R4 libraries +$ link xscreensaver-command,vms_axp.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_axp.opt/opt +$ endif diff --git a/driver/link_decc.com b/driver/link_decc.com new file mode 100644 index 00000000..d1de0d0a --- /dev/null +++ b/driver/link_decc.com @@ -0,0 +1,15 @@ +$! We fisrt test the version of DECW/Motif ; if 1.2 we need to link with new +$! X11R5 libraries +$@sys$update:decw$get_image_version sys$share:decw$xlibshr.exe decw$version +$ if f$extract(4,3,decw$version).eqs."1.2" +$ then +$! DECW/Motif 1.2 : link with X11R5 libraries +$ link xscreensaver-command,vms_decc_12.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_decc_12.opt/opt +$ else +$! Else, link with X11R4 libraries +$ link xscreensaver-command,vms_decc.opt/opt +$ link xscreensaver,demo,dialogs-xm,lock,passwd,stderr,subprocs,timers, - + windows,xset,vms-getpwnam,vms-hpwd,vms-validate,vms_decc.opt/opt +$ endif diff --git a/driver/lock.c b/driver/lock.c new file mode 100644 index 00000000..b0c4ec70 --- /dev/null +++ b/driver/lock.c @@ -0,0 +1,2268 @@ +/* lock.c --- handling the password dialog for locking-mode. + * xscreensaver, Copyright (c) 1993-2013 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. + */ + +/* Athena locking code contributed by Jon A. Christopher */ +/* Copyright 1997, with the same permissions as above. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include /* for time() */ +#include +#include +#include "xscreensaver.h" +#include "resources.h" +#include "mlstring.h" +#include "auth.h" + +#ifndef NO_LOCKING /* (mostly) whole file */ + +#ifdef HAVE_XHPDISABLERESET +# include + static void hp_lock_reset (saver_info *si, Bool lock_p); +#endif /* HAVE_XHPDISABLERESET */ + +#ifdef HAVE_XF86VMODE +# include + static void xfree_lock_mode_switch (saver_info *si, Bool lock_p); +#endif /* HAVE_XF86VMODE */ + +#ifdef HAVE_XF86MISCSETGRABKEYSSTATE +# include + static void xfree_lock_grab_smasher (saver_info *si, Bool lock_p); +#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ + +#ifdef HAVE_RANDR +# include +#endif /* HAVE_RANDR */ + +#ifdef _VROOT_H_ +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 */ + +extern char *getenv(const char *name); +extern int validate_user(char *name, char *password); + +static Bool +vms_passwd_valid_p(char *pw, Bool verbose_p) +{ + return (validate_user (getenv("USER"), typed_passwd) == 1); +} +# undef passwd_valid_p +# define passwd_valid_p vms_passwd_valid_p + +#endif /* VMS */ + +#define SAMPLE_INPUT "MMMMMMMMMMMM" + + +#undef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) + +typedef struct info_dialog_data info_dialog_data; + + +#define MAX_BYTES_PER_CHAR 8 /* UTF-8 uses no more than 3, I think */ +#define MAX_PASSWD_CHARS 128 /* Longest possible passphrase */ + +struct passwd_dialog_data { + + saver_screen_info *prompt_screen; + int previous_mouse_x, previous_mouse_y; + + /* "Characters" in the password may be a variable number of bytes long. + typed_passwd contains the raw bytes. + typed_passwd_char_size indicates the size in bytes of each character, + so that we can make backspace work. + */ + char typed_passwd [MAX_PASSWD_CHARS * MAX_BYTES_PER_CHAR]; + char typed_passwd_char_size [MAX_PASSWD_CHARS]; + + XtIntervalId timer; + int i_beam; + + float ratio; + Position x, y; + Dimension width; + Dimension height; + Dimension border_width; + + Bool echo_input; + Bool show_stars_p; /* "I regret that I have but one asterisk for my country." + -- Nathan Hale, 1776. */ + + char *heading_label; + char *body_label; + char *user_label; + mlstring *info_label; + /* The entry field shall only be displayed if prompt_label is not NULL */ + mlstring *prompt_label; + char *date_label; + char *passwd_string; + Bool passwd_changed_p; /* Whether the user entry field needs redrawing */ + Bool caps_p; /* Whether we saw a keypress with caps-lock on */ + char *unlock_label; + char *login_label; + char *uname_label; + + Bool show_uname_p; + + XFontStruct *heading_font; + XFontStruct *body_font; + XFontStruct *label_font; + XFontStruct *passwd_font; + XFontStruct *date_font; + XFontStruct *button_font; + XFontStruct *uname_font; + + Pixel foreground; + Pixel background; + Pixel border; + Pixel passwd_foreground; + Pixel passwd_background; + Pixel thermo_foreground; + Pixel thermo_background; + Pixel shadow_top; + Pixel shadow_bottom; + Pixel button_foreground; + Pixel button_background; + + Dimension preferred_logo_width, logo_width; + Dimension preferred_logo_height, logo_height; + Dimension thermo_width; + Dimension internal_border; + Dimension shadow_width; + + Dimension passwd_field_x, passwd_field_y; + Dimension passwd_field_width, passwd_field_height; + + Dimension unlock_button_x, unlock_button_y; + Dimension unlock_button_width, unlock_button_height; + + Dimension login_button_x, login_button_y; + Dimension login_button_width, login_button_height; + + Dimension thermo_field_x, thermo_field_y; + Dimension thermo_field_height; + + Pixmap logo_pixmap; + Pixmap logo_clipmask; + int logo_npixels; + unsigned long *logo_pixels; + + Cursor passwd_cursor; + Bool unlock_button_down_p; + Bool login_button_down_p; + Bool login_button_p; + Bool login_button_enabled_p; + Bool button_state_changed_p; /* Refers to both buttons */ + + Pixmap save_under; + Pixmap user_entry_pixmap; +}; + +static void draw_passwd_window (saver_info *si); +static void update_passwd_window (saver_info *si, const char *printed_passwd, + float ratio); +static void destroy_passwd_window (saver_info *si); +static void undo_vp_motion (saver_info *si); +static void finished_typing_passwd (saver_info *si, passwd_dialog_data *pw); +static void cleanup_passwd_window (saver_info *si); +static void restore_background (saver_info *si); + +extern void xss_authenticate(saver_info *si, Bool verbose_p); + +static int +new_passwd_window (saver_info *si) +{ + passwd_dialog_data *pw; + Screen *screen; + Colormap cmap; + char *f; + saver_screen_info *ssi = &si->screens [mouse_screen (si)]; + + pw = (passwd_dialog_data *) calloc (1, sizeof(*pw)); + if (!pw) + return -1; + + /* Display the button only if the "newLoginCommand" pref is non-null. + */ + pw->login_button_p = (si->prefs.new_login_command && + *si->prefs.new_login_command); + + pw->passwd_cursor = XCreateFontCursor (si->dpy, XC_top_left_arrow); + + pw->prompt_screen = ssi; + + screen = pw->prompt_screen->screen; + cmap = DefaultColormapOfScreen (screen); + + pw->show_stars_p = get_boolean_resource(si->dpy, "passwd.asterisks", + "Boolean"); + + pw->heading_label = get_string_resource (si->dpy, "passwd.heading.label", + "Dialog.Label.Label"); + pw->body_label = get_string_resource (si->dpy, "passwd.body.label", + "Dialog.Label.Label"); + pw->user_label = get_string_resource (si->dpy, "passwd.user.label", + "Dialog.Label.Label"); + pw->unlock_label = get_string_resource (si->dpy, "passwd.unlock.label", + "Dialog.Button.Label"); + pw->login_label = get_string_resource (si->dpy, "passwd.login.label", + "Dialog.Button.Label"); + + pw->date_label = get_string_resource (si->dpy, "dateFormat", "DateFormat"); + + if (!pw->heading_label) + pw->heading_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY"); + if (!pw->body_label) + pw->body_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY"); + if (!pw->user_label) pw->user_label = strdup("ERROR"); + if (!pw->date_label) pw->date_label = strdup("ERROR"); + if (!pw->unlock_label) pw->unlock_label = strdup("ERROR (UNLOCK)"); + if (!pw->login_label) pw->login_label = strdup ("ERROR (LOGIN)") ; + + /* Put the version number in the label. */ + { + char *s = (char *) malloc (strlen(pw->heading_label) + 20); + sprintf(s, pw->heading_label, si->version); + free (pw->heading_label); + 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->passwd_string = strdup(""); + + 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 (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(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(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(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(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); + + 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" ); + pw->border = get_pixel_resource (si->dpy, cmap, + "passwd.borderColor", + "Dialog.borderColor"); + + if (pw->foreground == pw->background) + { + /* Make sure the error messages show up. */ + pw->foreground = BlackPixelOfScreen (screen); + pw->background = WhitePixelOfScreen (screen); + } + + 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->preferred_logo_width = get_integer_resource (si->dpy, + "passwd.logo.width", + "Dialog.Logo.Width"); + pw->preferred_logo_height = get_integer_resource (si->dpy, + "passwd.logo.height", + "Dialog.Logo.Height"); + pw->thermo_width = get_integer_resource (si->dpy, "passwd.thermometer.width", + "Dialog.Thermometer.Width"); + pw->internal_border = get_integer_resource (si->dpy, + "passwd.internalBorderWidth", + "Dialog.InternalBorderWidth"); + pw->shadow_width = get_integer_resource (si->dpy, "passwd.shadowThickness", + "Dialog.ShadowThickness"); + + if (pw->preferred_logo_width == 0) pw->preferred_logo_width = 150; + if (pw->preferred_logo_height == 0) pw->preferred_logo_height = 150; + if (pw->internal_border == 0) pw->internal_border = 15; + if (pw->shadow_width == 0) pw->shadow_width = 4; + if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width; + + + /* We need to remember the mouse position and restore it afterward, or + sometimes (perhaps only with Xinerama?) the mouse gets warped to + inside the bounds of the lock dialog window. + */ + { + Window pointer_root, pointer_child; + int root_x, root_y, win_x, win_y; + unsigned int mask; + pw->previous_mouse_x = 0; + pw->previous_mouse_y = 0; + if (XQueryPointer (si->dpy, RootWindowOfScreen (pw->prompt_screen->screen), + &pointer_root, &pointer_child, + &root_x, &root_y, &win_x, &win_y, &mask)) + { + pw->previous_mouse_x = root_x; + pw->previous_mouse_y = root_y; + if (si->prefs.verbose_p) + fprintf (stderr, "%s: %d: mouse is at %d,%d.\n", + blurb(), pw->prompt_screen->number, + pw->previous_mouse_x, pw->previous_mouse_y); + } + else if (si->prefs.verbose_p) + fprintf (stderr, "%s: %d: unable to determine mouse position?\n", + blurb(), pw->prompt_screen->number); + } + + /* Before mapping the window, save a pixmap of the current screen. + When we lower the window, we restore these bits. This works, + because the running screenhack has already been sent SIGSTOP, so + we know nothing else is drawing right now! */ + { + XGCValues gcv; + GC gc; + pw->save_under = XCreatePixmap (si->dpy, + pw->prompt_screen->screensaver_window, + pw->prompt_screen->width, + pw->prompt_screen->height, + pw->prompt_screen->current_depth); + gcv.function = GXcopy; + gc = XCreateGC (si->dpy, pw->save_under, GCFunction, &gcv); + XCopyArea (si->dpy, pw->prompt_screen->screensaver_window, + pw->save_under, gc, + 0, 0, + pw->prompt_screen->width, pw->prompt_screen->height, + 0, 0); + XFreeGC (si->dpy, gc); + } + + si->pw_data = pw; + return 0; +} + + +Bool debug_passwd_window_p = False; /* used only by test-passwd.c */ + + +/** + * info_msg and prompt may be NULL. + */ +static int +make_passwd_window (saver_info *si, + const char *info_msg, + const char *prompt, + Bool echo) +{ + XSetWindowAttributes attrs; + unsigned long attrmask = 0; + passwd_dialog_data *pw; + Screen *screen; + Colormap cmap; + Dimension max_string_width_px; + saver_screen_info *ssi = &si->screens [mouse_screen (si)]; + + cleanup_passwd_window (si); + + if (! ssi) /* WTF? Trying to prompt while no screens connected? */ + return -1; + + if (!si->pw_data) + if (new_passwd_window (si) < 0) + return -1; + + if (!(pw = si->pw_data)) + return -1; + + pw->ratio = 1.0; + + pw->prompt_screen = ssi; + if (si->prefs.verbose_p) + fprintf (stderr, "%s: %d: creating password dialog (\"%s\")\n", + blurb(), pw->prompt_screen->number, + info_msg ? info_msg : ""); + + screen = pw->prompt_screen->screen; + cmap = DefaultColormapOfScreen (screen); + + pw->echo_input = echo; + + max_string_width_px = ssi->width + - pw->shadow_width * 4 + - pw->border_width * 2 + - pw->thermo_width + - pw->preferred_logo_width + - pw->internal_border * 2; + /* As the string wraps it makes the window taller which makes the logo wider + * which leaves less room for the text which makes the string wrap. Uh-oh, a + * loop. By wrapping at a bit less than the available width, there's some + * room for the dialog to grow without going off the edge of the screen. */ + max_string_width_px *= 0.75; + + if (!info_msg && senescent_p()) + info_msg = ("\n" + "This version of XScreenSaver\n" + "is very old! Please upgrade!\n"); + + pw->info_label = mlstring_new(info_msg ? info_msg : pw->body_label, + pw->label_font, max_string_width_px); + + { + int direction, ascent, descent; + XCharStruct overall; + + pw->width = 0; + pw->height = 0; + + /* Measure the heading_label. */ + XTextExtents (pw->heading_font, + pw->heading_label, strlen(pw->heading_label), + &direction, &ascent, &descent, &overall); + 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; + } + + { + Dimension w2 = 0, w3 = 0, button_w = 0; + Dimension h2 = 0, h3 = 0, button_h = 0; + const char *passwd_string = SAMPLE_INPUT; + + /* Measure the user_label. */ + XTextExtents (pw->label_font, + pw->user_label, strlen(pw->user_label), + &direction, &ascent, &descent, &overall); + if (overall.width > w2) w2 = overall.width; + h2 += ascent + descent; + + /* Measure the info_label. */ + if (pw->info_label->overall_width > pw->width) + pw->width = pw->info_label->overall_width; + h2 += pw->info_label->overall_height; + + /* Measure the user string. */ + XTextExtents (pw->passwd_font, + si->user, strlen(si->user), + &direction, &ascent, &descent, &overall); + overall.width += (pw->shadow_width * 4); + ascent += (pw->shadow_width * 4); + if (overall.width > w3) w3 = overall.width; + h3 += ascent + descent; + + /* Measure the (dummy) passwd_string. */ + if (prompt) + { + XTextExtents (pw->passwd_font, + passwd_string, strlen(passwd_string), + &direction, &ascent, &descent, &overall); + overall.width += (pw->shadow_width * 4); + ascent += (pw->shadow_width * 4); + if (overall.width > w3) w3 = overall.width; + h3 += ascent + descent; + + /* Measure the prompt_label. */ + max_string_width_px -= w3; + pw->prompt_label = mlstring_new (prompt, pw->label_font, + max_string_width_px); + + if (pw->prompt_label->overall_width > w2) + w2 = pw->prompt_label->overall_width; + + h2 += pw->prompt_label->overall_height; + + w2 = w2 + w3 + (pw->shadow_width * 2); + h2 = MAX (h2, h3); + } + + /* The "Unlock" button. */ + XTextExtents (pw->label_font, + pw->unlock_label, strlen(pw->unlock_label), + &direction, &ascent, &descent, &overall); + button_w = overall.width; + button_h = ascent + descent; + + /* Add some horizontal padding inside the button. */ + button_w += ascent; + + button_w += ((ascent + descent) / 2) + (pw->shadow_width * 2); + button_h += ((ascent + descent) / 2) + (pw->shadow_width * 2); + + pw->unlock_button_width = button_w; + pw->unlock_button_height = button_h; + + w2 = MAX (w2, button_w); + h2 += button_h * 1.5; + + /* The "New Login" button */ + pw->login_button_width = 0; + pw->login_button_height = 0; + + if (pw->login_button_p) + { + pw->login_button_enabled_p = True; + + /* Measure the "New Login" button */ + XTextExtents (pw->button_font, pw->login_label, + strlen (pw->login_label), + &direction, &ascent, &descent, &overall); + button_w = overall.width; + button_h = ascent + descent; + + /* Add some horizontal padding inside the buttons. */ + button_w += ascent; + + button_w += ((ascent + descent) / 2) + (pw->shadow_width * 2); + button_h += ((ascent + descent) / 2) + (pw->shadow_width * 2); + + pw->login_button_width = button_w; + pw->login_button_height = button_h; + + if (button_h > pw->unlock_button_height) + h2 += (button_h * 1.5 - pw->unlock_button_height * 1.5); + + /* Use (2 * shadow_width) spacing between the buttons. Another + (2 * shadow_width) is required to account for button shadows. */ + w2 = MAX (w2, + button_w + pw->unlock_button_width + + (pw->shadow_width * 4)); + } + + if (w2 > pw->width) pw->width = w2; + pw->height += h2; + } + + pw->width += (pw->internal_border * 2); + pw->height += (pw->internal_border * 4); + + pw->width += pw->thermo_width + (pw->shadow_width * 3); + + if (pw->preferred_logo_height > pw->height) + pw->height = pw->logo_height = pw->preferred_logo_height; + else if (pw->height > pw->preferred_logo_height) + pw->logo_height = pw->height; + + pw->logo_width = pw->logo_height; + + pw->width += pw->logo_width; + } + + attrmask |= CWOverrideRedirect; attrs.override_redirect = True; + + if (debug_passwd_window_p) + attrs.override_redirect = False; /* kludge for test-passwd.c */ + + attrmask |= CWEventMask; + attrs.event_mask = (ExposureMask | KeyPressMask | + ButtonPressMask | ButtonReleaseMask); + + /* Figure out where on the desktop to place the window so that it will + actually be visible; this takes into account virtual viewports as + well as Xinerama. */ + { + saver_screen_info *ssi = &si->screens [mouse_screen (si)]; + int x = ssi->x; + int y = ssi->y; + int w = ssi->width; + int h = ssi->height; + if (si->prefs.debug_p) w /= 2; + pw->x = x + ((w + pw->width) / 2) - pw->width; + pw->y = y + ((h + pw->height) / 2) - pw->height; + if (pw->x < x) pw->x = x; + if (pw->y < y) pw->y = y; + } + + pw->border_width = get_integer_resource (si->dpy, "passwd.borderWidth", + "Dialog.BorderWidth"); + + /* Only create the window the first time around */ + if (!si->passwd_dialog) + { + si->passwd_dialog = + XCreateWindow (si->dpy, + RootWindowOfScreen(screen), + pw->x, pw->y, pw->width, pw->height, pw->border_width, + DefaultDepthOfScreen (screen), InputOutput, + DefaultVisualOfScreen(screen), + attrmask, &attrs); + XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background); + XSetWindowBorder (si->dpy, si->passwd_dialog, pw->border); + + /* We use the default visual, not ssi->visual, so that the logo pixmap's + visual matches that of the si->passwd_dialog window. */ + pw->logo_pixmap = xscreensaver_logo (ssi->screen, + /* ssi->current_visual, */ + DefaultVisualOfScreen(screen), + si->passwd_dialog, cmap, + pw->background, + &pw->logo_pixels, &pw->logo_npixels, + &pw->logo_clipmask, True); + } + else /* On successive prompts, just resize the window */ + { + XWindowChanges wc; + unsigned int mask = CWX | CWY | CWWidth | CWHeight; + + wc.x = pw->x; + wc.y = pw->y; + wc.width = pw->width; + wc.height = pw->height; + + XConfigureWindow (si->dpy, si->passwd_dialog, mask, &wc); + } + + restore_background(si); + + XMapRaised (si->dpy, si->passwd_dialog); + XSync (si->dpy, False); + + move_mouse_grab (si, si->passwd_dialog, + pw->passwd_cursor, + pw->prompt_screen->number); + undo_vp_motion (si); + + si->pw_data = pw; + + if (cmap) + XInstallColormap (si->dpy, cmap); + draw_passwd_window (si); + + return 0; +} + + +static void +draw_passwd_window (saver_info *si) +{ + passwd_dialog_data *pw = si->pw_data; + XGCValues gcv; + GC gc1, gc2; + int spacing, height; + int x1, x2, x3, y1, y2; + int sw; + int tb_height; + + /* Force redraw */ + pw->passwd_changed_p = True; + pw->button_state_changed_p = True; + + /* This height is the height of all the elements, not to be confused with + * the overall window height which is pw->height. It is used to compute + * the amount of spacing (padding) between elements. */ + height = (pw->heading_font->ascent + pw->heading_font->descent + + pw->info_label->overall_height + + MAX (((pw->label_font->ascent + pw->label_font->descent) + + (pw->prompt_label ? pw->prompt_label->overall_height : 0)), + ((pw->passwd_font->ascent + pw->passwd_font->descent) + + (pw->shadow_width * 2)) * (pw->prompt_label ? 2 : 1)) + + 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); + + height += ((pw->button_font->ascent + pw->button_font->descent) * 2 + + 2 * pw->shadow_width); + + spacing = ((pw->height - 2 * pw->shadow_width + - pw->internal_border - height) + / 10); + + if (spacing < 0) spacing = 0; + + gcv.foreground = pw->foreground; + gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv); + gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv); + x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3); + x3 = pw->width - (pw->shadow_width * 2); + y1 = (pw->shadow_width * 2) + spacing + spacing; + + /* top heading + */ + XSetFont (si->dpy, gc1, pw->heading_font->fid); + sw = string_width (pw->heading_font, pw->heading_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent; + XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, + pw->heading_label, strlen(pw->heading_label)); + + /* 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)); + } + + /* the info_label (below uname) + */ + x2 = (x1 + ((x3 - x1 - pw->info_label->overall_width) / 2)); + y1 += spacing + pw->info_label->font_height / 2; + mlstring_draw(si->dpy, si->passwd_dialog, gc1, pw->info_label, + x2, y1); + y1 += pw->info_label->overall_height; + + + tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent + + (pw->shadow_width * 4)); + + /* the "User:" prompt + */ + y2 = y1; + XSetForeground (si->dpy, gc1, pw->foreground); + XSetFont (si->dpy, gc1, pw->label_font->fid); + y1 += (spacing + tb_height + pw->shadow_width); + x2 = (x1 + pw->internal_border + + MAX(string_width (pw->label_font, pw->user_label), + pw->prompt_label ? pw->prompt_label->overall_width : 0)); + XDrawString (si->dpy, si->passwd_dialog, gc1, + x2 - string_width (pw->label_font, pw->user_label), + y1 - pw->passwd_font->descent, + pw->user_label, strlen(pw->user_label)); + + /* the prompt_label prompt + */ + if (pw->prompt_label) + { + y1 += tb_height - pw->label_font->ascent + pw->shadow_width; + mlstring_draw(si->dpy, si->passwd_dialog, gc1, pw->prompt_label, + x2 - pw->prompt_label->overall_width, y1); + } + + /* the "user name" text field + */ + y1 = y2; + XSetForeground (si->dpy, gc1, pw->passwd_foreground); + XSetForeground (si->dpy, gc2, pw->passwd_background); + XSetFont (si->dpy, gc1, pw->passwd_font->fid); + y1 += (spacing + tb_height); + x2 += (pw->shadow_width * 4); + + pw->passwd_field_width = x3 - x2 - pw->internal_border; + pw->passwd_field_height = (pw->passwd_font->ascent + + pw->passwd_font->descent + + pw->shadow_width); + + XFillRectangle (si->dpy, si->passwd_dialog, gc2, + x2 - pw->shadow_width, + y1 - (pw->passwd_font->ascent + pw->passwd_font->descent), + pw->passwd_field_width, pw->passwd_field_height); + XDrawString (si->dpy, si->passwd_dialog, gc1, + x2, + y1 - pw->passwd_font->descent, + si->user, strlen(si->user)); + + /* the password/prompt text field + */ + if (pw->prompt_label) + { + y1 += (spacing + pw->prompt_label->overall_height + pw->shadow_width*2); + + pw->passwd_field_x = x2 - pw->shadow_width; + pw->passwd_field_y = y1 - (pw->passwd_font->ascent + + pw->passwd_font->descent); + } + + /* The shadow around the text fields + */ + y1 = y2; + y1 += (spacing + (pw->shadow_width * 3)); + x1 = x2 - (pw->shadow_width * 2); + x2 = pw->passwd_field_width + (pw->shadow_width * 2); + y2 = pw->passwd_field_height + (pw->shadow_width * 2); + + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + x1, y1, x2, y2, + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + + if (pw->prompt_label) + { + y1 += (spacing + pw->prompt_label->overall_height + pw->shadow_width*2); + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + x1, y1, x2, y2, + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + } + + + /* The date, below the text fields + */ + { + char buf[100]; + time_t now = time ((time_t *) 0); + struct tm *tm = localtime (&now); + memset (buf, 0, sizeof(buf)); + strftime (buf, sizeof(buf)-1, pw->date_label, tm); + + XSetFont (si->dpy, gc1, pw->date_font->fid); + y1 += pw->shadow_width; + y1 += (spacing + tb_height); + y1 += spacing/2; + sw = string_width (pw->date_font, buf); + x2 = x1 + x2 - sw; + XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, buf, strlen(buf)); + } + + /* Set up the GCs for the "New Login" and "Unlock" buttons. + */ + XSetForeground(si->dpy, gc1, pw->button_foreground); + XSetForeground(si->dpy, gc2, pw->button_background); + XSetFont(si->dpy, gc1, pw->button_font->fid); + + /* The "Unlock" button */ + x2 = pw->width - pw->internal_border - (pw->shadow_width * 2); + + /* right aligned button */ + x1 = x2 - pw->unlock_button_width; + + /* Add half the difference between y1 and the internal edge. + * It actually looks better if the internal border is ignored. */ + y1 += ((pw->height - MAX (pw->unlock_button_height, pw->login_button_height) + - spacing - y1) + / 2); + + pw->unlock_button_x = x1; + pw->unlock_button_y = y1; + + /* The "New Login" button + */ + if (pw->login_button_p) + { + /* Using the same GC as for the Unlock button */ + + sw = string_width (pw->button_font, pw->login_label); + + /* left aligned button */ + x1 = (pw->logo_width + pw->thermo_width + (pw->shadow_width * 3) + + pw->internal_border); + + pw->login_button_x = x1; + pw->login_button_y = y1; + } + + /* The logo + */ + x1 = pw->shadow_width * 6; + y1 = pw->shadow_width * 6; + x2 = pw->logo_width - (pw->shadow_width * 12); + y2 = pw->logo_height - (pw->shadow_width * 12); + + if (pw->logo_pixmap) + { + Window root; + int x, y; + unsigned int w, h, bw, d; + 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, + x1 + ((x2 - (int)w) / 2), + y1 + ((y2 - (int)h) / 2), + 1); + else + XCopyArea (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1, + 0, 0, w, h, + x1 + ((x2 - (int)w) / 2), + y1 + ((y2 - (int)h) / 2)); + } + + /* The thermometer + */ + XSetForeground (si->dpy, gc1, pw->thermo_foreground); + XSetForeground (si->dpy, gc2, pw->thermo_background); + + pw->thermo_field_x = pw->logo_width + pw->shadow_width; + pw->thermo_field_y = pw->shadow_width * 5; + pw->thermo_field_height = pw->height - (pw->shadow_width * 10); + +#if 0 + /* Solid border inside the logo box. */ + XSetForeground (si->dpy, gc1, pw->foreground); + XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1); +#endif + + /* The shadow around the logo + */ + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + pw->shadow_width * 4, + pw->shadow_width * 4, + pw->logo_width - (pw->shadow_width * 8), + pw->logo_height - (pw->shadow_width * 8), + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + + /* The shadow around the thermometer + */ + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + pw->logo_width, + pw->shadow_width * 4, + pw->thermo_width + (pw->shadow_width * 2), + pw->height - (pw->shadow_width * 8), + pw->shadow_width, + pw->shadow_bottom, pw->shadow_top); + +#if 1 + /* Solid border inside the thermometer. */ + XSetForeground (si->dpy, gc1, pw->foreground); + XDrawRectangle (si->dpy, si->passwd_dialog, gc1, + pw->thermo_field_x, pw->thermo_field_y, + pw->thermo_width - 1, pw->thermo_field_height - 1); +#endif + + /* The shadow around the whole window + */ + draw_shaded_rectangle (si->dpy, si->passwd_dialog, + 0, 0, pw->width, pw->height, pw->shadow_width, + pw->shadow_top, pw->shadow_bottom); + + XFreeGC (si->dpy, gc1); + XFreeGC (si->dpy, gc2); + + update_passwd_window (si, pw->passwd_string, pw->ratio); +} + +static void +draw_button(Display *dpy, + Drawable dialog, + XFontStruct *font, + unsigned long foreground, unsigned long background, + char *label, + int x, int y, + int width, int height, + int shadow_width, + Pixel shadow_light, Pixel shadow_dark, + Bool button_down) +{ + XGCValues gcv; + GC gc1, gc2; + int sw; + int label_x, label_y; + + gcv.foreground = foreground; + gcv.font = font->fid; + gc1 = XCreateGC(dpy, dialog, GCForeground|GCFont, &gcv); + gcv.foreground = background; + gc2 = XCreateGC(dpy, dialog, GCForeground, &gcv); + + XFillRectangle(dpy, dialog, gc2, + x, y, width, height); + + sw = string_width(font, label); + + label_x = x + ((width - sw) / 2); + label_y = (y + (height - (font->ascent + font->descent)) / 2 + font->ascent); + + if (button_down) + { + label_x += 2; + label_y += 2; + } + + XDrawString(dpy, dialog, gc1, label_x, label_y, label, strlen(label)); + + XFreeGC(dpy, gc1); + XFreeGC(dpy, gc2); + + draw_shaded_rectangle(dpy, dialog, x, y, width, height, + shadow_width, shadow_light, shadow_dark); +} + +static void +update_passwd_window (saver_info *si, const char *printed_passwd, float ratio) +{ + passwd_dialog_data *pw = si->pw_data; + XGCValues gcv; + GC gc1, gc2; + int x, y; + XRectangle rects[1]; + + pw->ratio = ratio; + gcv.foreground = pw->passwd_foreground; + gcv.font = pw->passwd_font->fid; + gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv); + gcv.foreground = pw->passwd_background; + gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv); + + if (printed_passwd) + { + char *s = strdup (printed_passwd); + if (pw->passwd_string) free (pw->passwd_string); + pw->passwd_string = s; + } + + if (pw->prompt_label) + { + + /* the "password" text field + */ + rects[0].x = pw->passwd_field_x; + rects[0].y = pw->passwd_field_y; + rects[0].width = pw->passwd_field_width; + rects[0].height = pw->passwd_field_height; + + /* The user entry (password) field is double buffered. + * This avoids flickering, particularly in synchronous mode. */ + + if (pw->passwd_changed_p) + { + pw->passwd_changed_p = False; + + if (pw->user_entry_pixmap) + { + XFreePixmap(si->dpy, pw->user_entry_pixmap); + pw->user_entry_pixmap = 0; + } + + pw->user_entry_pixmap = + XCreatePixmap (si->dpy, si->passwd_dialog, + rects[0].width, rects[0].height, + DefaultDepthOfScreen (pw->prompt_screen->screen)); + + XFillRectangle (si->dpy, pw->user_entry_pixmap, gc2, + 0, 0, rects[0].width, rects[0].height); + + XDrawString (si->dpy, pw->user_entry_pixmap, gc1, + pw->shadow_width, + pw->passwd_font->ascent, + pw->passwd_string, strlen(pw->passwd_string)); + + /* Ensure the new pixmap gets copied to the window */ + pw->i_beam = 0; + + } + + /* The I-beam + */ + if (pw->i_beam == 0) + { + /* Make the I-beam disappear */ + XCopyArea(si->dpy, pw->user_entry_pixmap, si->passwd_dialog, gc2, + 0, 0, rects[0].width, rects[0].height, + rects[0].x, rects[0].y); + } + else if (pw->i_beam == 1) + { + /* Make the I-beam appear */ + x = (rects[0].x + pw->shadow_width + + string_width (pw->passwd_font, pw->passwd_string)); + y = rects[0].y + pw->shadow_width; + + if (x > rects[0].x + rects[0].width - 1) + x = rects[0].x + rects[0].width - 1; + XDrawLine (si->dpy, si->passwd_dialog, gc1, + x, y, + x, y + pw->passwd_font->ascent + + pw->passwd_font->descent-1); + } + + pw->i_beam = (pw->i_beam + 1) % 4; + + } + + /* the thermometer + */ + y = (pw->thermo_field_height - 2) * (1.0 - pw->ratio); + if (y > 0) + { + XFillRectangle (si->dpy, si->passwd_dialog, gc2, + pw->thermo_field_x + 1, + pw->thermo_field_y + 1, + pw->thermo_width-2, + y); + XSetForeground (si->dpy, gc1, pw->thermo_foreground); + XFillRectangle (si->dpy, si->passwd_dialog, gc1, + pw->thermo_field_x + 1, + pw->thermo_field_y + 1 + y, + pw->thermo_width-2, + MAX (0, pw->thermo_field_height - y - 2)); + } + + if (pw->button_state_changed_p) + { + pw->button_state_changed_p = False; + + /* The "Unlock" button + */ + draw_button(si->dpy, si->passwd_dialog, pw->button_font, + pw->button_foreground, pw->button_background, + pw->unlock_label, + pw->unlock_button_x, pw->unlock_button_y, + pw->unlock_button_width, pw->unlock_button_height, + pw->shadow_width, + (pw->unlock_button_down_p ? pw->shadow_bottom : + pw->shadow_top), + (pw->unlock_button_down_p ? pw->shadow_top : + pw->shadow_bottom), + pw->unlock_button_down_p); + + /* The "New Login" button + */ + if (pw->login_button_p) + { + draw_button(si->dpy, si->passwd_dialog, pw->button_font, + (pw->login_button_enabled_p + ? pw->passwd_foreground + : pw->shadow_bottom), + pw->button_background, + pw->login_label, + pw->login_button_x, pw->login_button_y, + pw->login_button_width, pw->login_button_height, + pw->shadow_width, + (pw->login_button_down_p + ? pw->shadow_bottom + : pw->shadow_top), + (pw->login_button_down_p + ? pw->shadow_top + : pw->shadow_bottom), + pw->login_button_down_p); + } + } + + XFreeGC (si->dpy, gc1); + XFreeGC (si->dpy, gc2); + XSync (si->dpy, False); +} + + +void +restore_background (saver_info *si) +{ + passwd_dialog_data *pw = si->pw_data; + saver_screen_info *ssi = pw->prompt_screen; + XGCValues gcv; + GC gc; + + gcv.function = GXcopy; + + gc = XCreateGC (si->dpy, ssi->screensaver_window, GCFunction, &gcv); + + XCopyArea (si->dpy, pw->save_under, + ssi->screensaver_window, gc, + 0, 0, + ssi->width, ssi->height, + 0, 0); + + XFreeGC (si->dpy, gc); +} + + +/* Frees anything created by make_passwd_window */ +static void +cleanup_passwd_window (saver_info *si) +{ + passwd_dialog_data *pw; + + if (!(pw = si->pw_data)) + return; + + if (pw->info_label) + { + mlstring_free(pw->info_label); + pw->info_label = 0; + } + + if (pw->prompt_label) + { + mlstring_free(pw->prompt_label); + pw->prompt_label = 0; + } + + memset (pw->typed_passwd, 0, sizeof(pw->typed_passwd)); + memset (pw->typed_passwd_char_size, 0, sizeof(pw->typed_passwd_char_size)); + memset (pw->passwd_string, 0, strlen(pw->passwd_string)); + + if (pw->timer) + { + XtRemoveTimeOut (pw->timer); + pw->timer = 0; + } + + if (pw->user_entry_pixmap) + { + XFreePixmap(si->dpy, pw->user_entry_pixmap); + pw->user_entry_pixmap = 0; + } +} + + +static void +destroy_passwd_window (saver_info *si) +{ + saver_preferences *p = &si->prefs; + passwd_dialog_data *pw = si->pw_data; + saver_screen_info *ssi = pw->prompt_screen; + Colormap cmap = DefaultColormapOfScreen (ssi->screen); + Pixel black = BlackPixelOfScreen (ssi->screen); + Pixel white = WhitePixelOfScreen (ssi->screen); + XEvent event; + + cleanup_passwd_window (si); + + if (si->cached_passwd) + { + char *wipe = si->cached_passwd; + + while (*wipe) + *wipe++ = '\0'; + + free(si->cached_passwd); + si->cached_passwd = NULL; + } + + move_mouse_grab (si, RootWindowOfScreen (ssi->screen), + ssi->cursor, ssi->number); + + if (pw->passwd_cursor) + XFreeCursor (si->dpy, pw->passwd_cursor); + + if (p->verbose_p) + fprintf (stderr, "%s: %d: moving mouse back to %d,%d.\n", + blurb(), ssi->number, + pw->previous_mouse_x, pw->previous_mouse_y); + + XWarpPointer (si->dpy, None, RootWindowOfScreen (ssi->screen), + 0, 0, 0, 0, + pw->previous_mouse_x, pw->previous_mouse_y); + XSync (si->dpy, False); + + while (XCheckMaskEvent (si->dpy, PointerMotionMask, &event)) + if (p->verbose_p) + fprintf (stderr, "%s: discarding MotionNotify event.\n", blurb()); + +#ifdef HAVE_XINPUT + if (si->using_xinput_extension && si->xinput_DeviceMotionNotify) + while (XCheckTypedEvent (si->dpy, si->xinput_DeviceMotionNotify, &event)) + if (p->verbose_p) + fprintf (stderr, "%s: discarding DeviceMotionNotify event.\n", + blurb()); +#endif + + if (si->passwd_dialog) + { + if (si->prefs.verbose_p) + fprintf (stderr, "%s: %d: destroying password dialog.\n", + blurb(), pw->prompt_screen->number); + + XDestroyWindow (si->dpy, si->passwd_dialog); + si->passwd_dialog = 0; + } + + if (pw->save_under) + { + restore_background(si); + XFreePixmap (si->dpy, pw->save_under); + pw->save_under = 0; + } + + if (pw->heading_label) free (pw->heading_label); + if (pw->body_label) free (pw->body_label); + if (pw->user_label) free (pw->user_label); + if (pw->date_label) free (pw->date_label); + if (pw->login_label) free (pw->login_label); + if (pw->unlock_label) free (pw->unlock_label); + 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); + if (pw->label_font) XFreeFont (si->dpy, pw->label_font); + 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); + if (pw->background != black && pw->background != white) + XFreeColors (si->dpy, cmap, &pw->background, 1, 0L); + if (!(pw->button_foreground == black || pw->button_foreground == white)) + XFreeColors (si->dpy, cmap, &pw->button_foreground, 1, 0L); + if (!(pw->button_background == black || pw->button_background == white)) + XFreeColors (si->dpy, cmap, &pw->button_background, 1, 0L); + if (pw->passwd_foreground != black && pw->passwd_foreground != white) + XFreeColors (si->dpy, cmap, &pw->passwd_foreground, 1, 0L); + if (pw->passwd_background != black && pw->passwd_background != white) + XFreeColors (si->dpy, cmap, &pw->passwd_background, 1, 0L); + if (pw->thermo_foreground != black && pw->thermo_foreground != white) + XFreeColors (si->dpy, cmap, &pw->thermo_foreground, 1, 0L); + if (pw->thermo_background != black && pw->thermo_background != white) + XFreeColors (si->dpy, cmap, &pw->thermo_background, 1, 0L); + if (pw->shadow_top != black && pw->shadow_top != white) + XFreeColors (si->dpy, cmap, &pw->shadow_top, 1, 0L); + if (pw->shadow_bottom != black && pw->shadow_bottom != white) + XFreeColors (si->dpy, cmap, &pw->shadow_bottom, 1, 0L); + + 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) + XFreeColors (si->dpy, cmap, pw->logo_pixels, pw->logo_npixels, 0L); + free (pw->logo_pixels); + pw->logo_pixels = 0; + pw->logo_npixels = 0; + } + + if (pw->save_under) + XFreePixmap (si->dpy, pw->save_under); + + if (cmap) + XInstallColormap (si->dpy, cmap); + + memset (pw, 0, sizeof(*pw)); + free (pw); + si->pw_data = 0; +} + + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + + +#ifdef HAVE_XHPDISABLERESET +/* This function enables and disables the C-Sh-Reset hot-key, which + normally resets the X server (logging out the logged-in user.) + We don't want random people to be able to do that while the + screen is locked. + */ +static void +hp_lock_reset (saver_info *si, Bool lock_p) +{ + static Bool hp_locked_p = False; + + /* Calls to XHPDisableReset and XHPEnableReset must be balanced, + or BadAccess errors occur. (It's ok for this to be global, + since it affects the whole machine, not just the current screen.) + */ + if (hp_locked_p == lock_p) + return; + + if (lock_p) + XHPDisableReset (si->dpy); + else + XHPEnableReset (si->dpy); + hp_locked_p = lock_p; +} +#endif /* HAVE_XHPDISABLERESET */ + + +#ifdef HAVE_XF86MISCSETGRABKEYSSTATE + +/* This function enables and disables the Ctrl-Alt-KP_star and + Ctrl-Alt-KP_slash hot-keys, which (in XFree86 4.2) break any + grabs and/or kill the grabbing client. That would effectively + unlock the screen, so we don't like that. + + The Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash hot-keys only exist + if AllowDeactivateGrabs and/or AllowClosedownGrabs are turned on + in XF86Config. I believe they are disabled by default. + + This does not affect any other keys (specifically Ctrl-Alt-BS or + Ctrl-Alt-F1) but I wish it did. Maybe it will someday. + */ +static void +xfree_lock_grab_smasher (saver_info *si, Bool lock_p) +{ + saver_preferences *p = &si->prefs; + int status; + int event, error; + XErrorHandler old_handler; + + if (!XF86MiscQueryExtension(si->dpy, &event, &error)) + return; + + XSync (si->dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + XSync (si->dpy, False); + status = XF86MiscSetGrabKeysState (si->dpy, !lock_p); + XSync (si->dpy, False); + if (error_handler_hit_p) status = 666; + + if (!lock_p && status == MiscExtGrabStateAlready) + status = MiscExtGrabStateSuccess; /* shut up, consider this success */ + + if (p->verbose_p && status != MiscExtGrabStateSuccess) + fprintf (stderr, "%s: error: XF86MiscSetGrabKeysState(%d) returned %s\n", + blurb(), !lock_p, + (status == MiscExtGrabStateSuccess ? "MiscExtGrabStateSuccess" : + status == MiscExtGrabStateLocked ? "MiscExtGrabStateLocked" : + status == MiscExtGrabStateAlready ? "MiscExtGrabStateAlready" : + status == 666 ? "an X error" : + "unknown value")); + + XSync (si->dpy, False); + XSetErrorHandler (old_handler); + XSync (si->dpy, False); +} +#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ + + + +/* This function enables and disables the C-Alt-Plus and C-Alt-Minus + hot-keys, which normally change the resolution of the X server. + We don't want people to be able to switch the server resolution + while the screen is locked, because if they switch to a higher + resolution, it could cause part of the underlying desktop to become + exposed. + */ +#ifdef HAVE_XF86VMODE + +static void +xfree_lock_mode_switch (saver_info *si, Bool lock_p) +{ + static Bool any_mode_locked_p = False; + saver_preferences *p = &si->prefs; + int screen; + int real_nscreens = ScreenCount (si->dpy); + int event, error; + Bool status; + XErrorHandler old_handler; + + if (any_mode_locked_p == lock_p) + return; + if (!XF86VidModeQueryExtension (si->dpy, &event, &error)) + return; + + for (screen = 0; screen < real_nscreens; screen++) + { + XSync (si->dpy, False); + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + error_handler_hit_p = False; + status = XF86VidModeLockModeSwitch (si->dpy, screen, lock_p); + XSync (si->dpy, False); + XSetErrorHandler (old_handler); + if (error_handler_hit_p) status = False; + + if (status) + any_mode_locked_p = lock_p; + + if (!status && (p->verbose_p || !lock_p)) + /* Only print this when verbose, or when we locked but can't unlock. + I tried printing this message whenever it comes up, but + mode-locking always fails if DontZoom is set in XF86Config. */ + fprintf (stderr, "%s: %d: unable to %s mode switching!\n", + blurb(), screen, (lock_p ? "lock" : "unlock")); + else if (p->verbose_p) + fprintf (stderr, "%s: %d: %s mode switching.\n", + blurb(), screen, (lock_p ? "locked" : "unlocked")); + } +} +#endif /* HAVE_XF86VMODE */ + + +/* If the viewport has been scrolled since the screen was blanked, + then scroll it back to where it belongs. This function only exists + to patch over a very brief race condition. + */ +static void +undo_vp_motion (saver_info *si) +{ +#ifdef HAVE_XF86VMODE + saver_preferences *p = &si->prefs; + int screen; + int real_nscreens = ScreenCount (si->dpy); + int event, error; + + if (!XF86VidModeQueryExtension (si->dpy, &event, &error)) + return; + + for (screen = 0; screen < real_nscreens; screen++) + { + saver_screen_info *ssi = &si->screens[screen]; + int x, y; + Bool status; + + if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1) + break; + if (!XF86VidModeGetViewPort (si->dpy, screen, &x, &y)) + return; + if (ssi->blank_vp_x == x && ssi->blank_vp_y == y) + return; + + /* We're going to move the viewport. The mouse has just been grabbed on + (and constrained to, thus warped to) the password window, so it is no + longer near the edge of the screen. However, wait a bit anyway, just + to make sure the server drains its last motion event, so that the + screen doesn't continue to scroll after we've reset the viewport. + */ + XSync (si->dpy, False); + usleep (250000); /* 1/4 second */ + XSync (si->dpy, False); + + status = XF86VidModeSetViewPort (si->dpy, screen, + ssi->blank_vp_x, ssi->blank_vp_y); + + if (!status) + fprintf (stderr, + "%s: %d: unable to move vp from (%d,%d) back to (%d,%d)!\n", + blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y); + else if (p->verbose_p) + fprintf (stderr, + "%s: %d: vp moved to (%d,%d); moved it back to (%d,%d).\n", + blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y); + } +#endif /* HAVE_XF86VMODE */ +} + + + +/* Interactions + */ + +static void +passwd_animate_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + int tick = 166; + passwd_dialog_data *pw = si->pw_data; + + if (!pw) return; + + pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick)); + if (pw->ratio < 0) + { + pw->ratio = 0; + if (si->unlock_state == ul_read) + si->unlock_state = ul_time; + } + + update_passwd_window (si, 0, pw->ratio); + + if (si->unlock_state == ul_read) + pw->timer = XtAppAddTimeOut (si->app, tick, passwd_animate_timer, + (XtPointer) si); + else + pw->timer = 0; + + idle_timer ((XtPointer) si, 0); +} + + +static XComposeStatus *compose_status; + +static void +handle_login_button (saver_info *si, XEvent *event) +{ + saver_preferences *p = &si->prefs; + Bool mouse_in_box = False; + Bool hit_p = False; + passwd_dialog_data *pw = si->pw_data; + saver_screen_info *ssi = pw->prompt_screen; + + if (! pw->login_button_enabled_p) + return; + + mouse_in_box = + (event->xbutton.x >= pw->login_button_x && + event->xbutton.x <= pw->login_button_x + pw->login_button_width && + event->xbutton.y >= pw->login_button_y && + event->xbutton.y <= pw->login_button_y + pw->login_button_height); + + if (ButtonRelease == event->xany.type && + pw->login_button_down_p && + mouse_in_box) + { + /* Only allow them to press the button once: don't want to + accidentally launch a dozen gdm choosers if the machine + is being slow. + */ + hit_p = True; + pw->login_button_enabled_p = False; + } + + pw->login_button_down_p = (mouse_in_box && + ButtonRelease != event->xany.type); + + update_passwd_window (si, 0, pw->ratio); + + if (hit_p) + fork_and_exec (ssi, p->new_login_command); +} + + +static void +handle_unlock_button (saver_info *si, XEvent *event) +{ + Bool mouse_in_box = False; + passwd_dialog_data *pw = si->pw_data; + + mouse_in_box = + (event->xbutton.x >= pw->unlock_button_x && + event->xbutton.x <= pw->unlock_button_x + pw->unlock_button_width && + event->xbutton.y >= pw->unlock_button_y && + event->xbutton.y <= pw->unlock_button_y + pw->unlock_button_height); + + if (ButtonRelease == event->xany.type && + pw->unlock_button_down_p && + mouse_in_box) + finished_typing_passwd (si, pw); + + pw->unlock_button_down_p = (mouse_in_box && + ButtonRelease != event->xany.type); +} + + +static void +finished_typing_passwd (saver_info *si, passwd_dialog_data *pw) +{ + if (si->unlock_state == ul_read) + { + update_passwd_window (si, "Checking...", pw->ratio); + XSync (si->dpy, False); + + si->unlock_state = ul_finished; + update_passwd_window (si, "", pw->ratio); + } +} + +static void +handle_passwd_key (saver_info *si, XKeyEvent *event) +{ + passwd_dialog_data *pw = si->pw_data; + unsigned char decoded [MAX_BYTES_PER_CHAR * 10]; /* leave some slack */ + KeySym keysym = 0; + + /* XLookupString may return more than one character via XRebindKeysym; + and on some systems it returns multi-byte UTF-8 characters (contrary + to its documentation, which says it returns only Latin1.) + + It seems to only do so, however, if setlocale() has been called. + See the code inside ENABLE_NLS in xscreensaver.c. + */ + int decoded_size = XLookupString (event, (char *)decoded, sizeof(decoded), + &keysym, compose_status); + +#if 0 + { + const char *ks = XKeysymToString (keysym); + int i; + fprintf(stderr, "## %-12s\t=> %d\t", (ks ? ks : "(null)"), decoded_size); + for (i = 0; i < decoded_size; i++) + fprintf(stderr, "%c", decoded[i]); + fprintf(stderr, "\t"); + for (i = 0; i < decoded_size; i++) + fprintf(stderr, "\\%03o", ((unsigned char *)decoded)[i]); + fprintf(stderr, "\n"); + } +#endif + + if (decoded_size > MAX_BYTES_PER_CHAR) + { + /* The multi-byte character returned is too large. */ + XBell (si->dpy, 0); + return; + } + + decoded[decoded_size] = 0; + pw->passwd_changed_p = True; + + /* Add 10% to the time remaining every time a key is pressed. */ + pw->ratio += 0.1; + if (pw->ratio > 1) pw->ratio = 1; + + if (decoded_size == 1) /* Handle single-char commands */ + { + switch (*decoded) + { + case '\010': case '\177': /* Backspace */ + { + /* kludgey way to get the number of "logical" characters. */ + int nchars = strlen (pw->typed_passwd_char_size); + int nbytes = strlen (pw->typed_passwd); + if (nbytes <= 0) + XBell (si->dpy, 0); + else + { + int i; + for (i = pw->typed_passwd_char_size[nchars-1]; i >= 0; i--) + { + if (nbytes < 0) abort(); + pw->typed_passwd[nbytes--] = 0; + } + pw->typed_passwd_char_size[nchars-1] = 0; + } + } + break; + + case '\012': case '\015': /* Enter */ + finished_typing_passwd (si, pw); + break; + + case '\033': /* Escape */ + si->unlock_state = ul_cancel; + break; + + case '\025': case '\030': /* Erase line */ + memset (pw->typed_passwd, 0, sizeof (pw->typed_passwd)); + memset (pw->typed_passwd_char_size, 0, + sizeof (pw->typed_passwd_char_size)); + break; + + default: + if (*decoded < ' ' && *decoded != '\t') /* Other ctrl char */ + XBell (si->dpy, 0); + else + goto SELF_INSERT; + break; + } + } + else + { + int nbytes, nchars; + SELF_INSERT: + nbytes = strlen (pw->typed_passwd); + nchars = strlen (pw->typed_passwd_char_size); + if (nchars + 1 >= sizeof (pw->typed_passwd_char_size)-1 || + nbytes + decoded_size >= sizeof (pw->typed_passwd)-1) /* overflow */ + XBell (si->dpy, 0); + else + { + pw->typed_passwd_char_size[nchars] = decoded_size; + pw->typed_passwd_char_size[nchars+1] = 0; + memcpy (pw->typed_passwd + nbytes, decoded, decoded_size); + pw->typed_passwd[nbytes + decoded_size] = 0; + } + } + + if (pw->echo_input) + { + /* If the input is wider than the text box, only show the last portion, + to simulate a horizontally-scrolling text field. */ + int chars_in_pwfield = (pw->passwd_field_width / + pw->passwd_font->max_bounds.width); + const char *output = pw->typed_passwd; + if (strlen(output) > chars_in_pwfield) + output += (strlen(output) - chars_in_pwfield); + update_passwd_window (si, output, pw->ratio); + } + else if (pw->show_stars_p) + { + int nchars = strlen (pw->typed_passwd_char_size); + char *stars = 0; + stars = (char *) malloc(nchars + 1); + memset (stars, '*', nchars); + stars[nchars] = 0; + update_passwd_window (si, stars, pw->ratio); + free (stars); + } + else + { + update_passwd_window (si, "", pw->ratio); + } +} + + +static void +passwd_event_loop (saver_info *si) +{ + saver_preferences *p = &si->prefs; + char *msg = 0; + + /* We have to go through this union bullshit because gcc-4.4.0 has + stricter struct-aliasing rules. Without this, the optimizer + can fuck things up. + */ + union { + XEvent x_event; +# ifdef HAVE_RANDR + XRRScreenChangeNotifyEvent xrr_event; +# endif /* HAVE_RANDR */ + } event; + + passwd_animate_timer ((XtPointer) si, 0); + + while (si->unlock_state == ul_read) + { + XtAppNextEvent (si->app, &event.x_event); + +#ifdef HAVE_RANDR + if (si->using_randr_extension && + (event.x_event.type == + (si->randr_event_number + RRScreenChangeNotify))) + { + /* The Resize and Rotate extension sends an event when the + size, rotation, or refresh rate of any screen has changed. */ + + if (p->verbose_p) + { + /* XRRRootToScreen is in Xrandr.h 1.4, 2001/06/07 */ + int screen = XRRRootToScreen(si->dpy, event.xrr_event.window); + fprintf (stderr, "%s: %d: screen change event received\n", + blurb(), screen); + } + +#ifdef RRScreenChangeNotifyMask + /* Inform Xlib that it's ok to update its data structures. */ + XRRUpdateConfiguration(&event.x_event); /* Xrandr.h 1.9, 2002/09/29*/ +#endif /* RRScreenChangeNotifyMask */ + + /* Resize the existing xscreensaver windows and cached ssi data. */ + if (update_screen_layout (si)) + { + if (p->verbose_p) + { + fprintf (stderr, "%s: new layout:\n", blurb()); + describe_monitor_layout (si); + } + resize_screensaver_window (si); + } + } + else +#endif /* HAVE_RANDR */ + + if (event.x_event.xany.window == si->passwd_dialog && + event.x_event.xany.type == Expose) + draw_passwd_window (si); + else if (event.x_event.xany.type == KeyPress) + { + handle_passwd_key (si, &event.x_event.xkey); + si->pw_data->caps_p = (event.x_event.xkey.state & LockMask); + } + else if (event.x_event.xany.type == ButtonPress || + event.x_event.xany.type == ButtonRelease) + { + si->pw_data->button_state_changed_p = True; + handle_unlock_button (si, &event.x_event); + if (si->pw_data->login_button_p) + handle_login_button (si, &event.x_event); + } + else + XtDispatchEvent (&event.x_event); + } + + switch (si->unlock_state) + { + case ul_cancel: msg = ""; break; + case ul_time: msg = "Timed out!"; break; + case ul_finished: msg = "Checking..."; break; + default: msg = 0; break; + } + + if (p->verbose_p) + switch (si->unlock_state) { + case ul_cancel: + fprintf (stderr, "%s: input cancelled.\n", blurb()); break; + case ul_time: + fprintf (stderr, "%s: input timed out.\n", blurb()); break; + case ul_finished: + fprintf (stderr, "%s: input finished.\n", blurb()); break; + default: break; + } + + if (msg) + { + si->pw_data->i_beam = 0; + update_passwd_window (si, msg, 0.0); + XSync (si->dpy, False); + + /* Swallow all pending KeyPress/KeyRelease events. */ + { + XEvent e; + while (XCheckMaskEvent (si->dpy, KeyPressMask|KeyReleaseMask, &e)) + ; + } + } +} + + +static void +handle_typeahead (saver_info *si) +{ + passwd_dialog_data *pw = si->pw_data; + int i; + if (!si->unlock_typeahead) + return; + + pw->passwd_changed_p = True; + + i = strlen (si->unlock_typeahead); + if (i >= sizeof(pw->typed_passwd) - 1) + i = sizeof(pw->typed_passwd) - 1; + + memcpy (pw->typed_passwd, si->unlock_typeahead, i); + pw->typed_passwd [i] = 0; + { + int j; + char *c = pw->typed_passwd_char_size; + for (j = 0; j < i; j++) + *c++ = 1; + *c = 0; + } + + memset (si->unlock_typeahead, '*', strlen(si->unlock_typeahead)); + si->unlock_typeahead[i] = 0; + update_passwd_window (si, si->unlock_typeahead, pw->ratio); + + free (si->unlock_typeahead); + si->unlock_typeahead = 0; +} + + +/** + * Returns a copy of the input string with trailing whitespace removed. + * Whitespace is anything considered so by isspace(). + * It is safe to call this with NULL, in which case NULL will be returned. + * The returned string (if not NULL) should be freed by the caller with free(). + */ +static char * +remove_trailing_whitespace(const char *str) +{ + size_t len; + char *newstr, *chr; + + if (!str) + return NULL; + + len = strlen(str); + + newstr = malloc(len + 1); + if (!newstr) + return NULL; + + (void) strcpy(newstr, str); + chr = newstr + len; + while (isspace(*--chr) && chr >= newstr) + *chr = '\0'; + + return newstr; +} + + +/* + * The authentication conversation function. + * Like a PAM conversation function, this accepts multiple messages in a single + * round. It then splits them into individual messages for display on the + * passwd dialog. A message sequence of info or error followed by a prompt will + * be reduced into a single dialog window. + * + * Returns 0 on success or -1 if some problem occurred (cancelled, OOM, etc.) + */ +int +gui_auth_conv(int num_msg, + const struct auth_message auth_msgs[], + struct auth_response **resp, + saver_info *si) +{ + int i; + const char *info_msg, *prompt; + struct auth_response *responses; + + if (si->unlock_state == ul_cancel || + si->unlock_state == ul_time) + /* If we've already cancelled or timed out in this PAM conversation, + don't prompt again even if PAM asks us to! */ + return -1; + + if (!(responses = calloc(num_msg, sizeof(struct auth_response)))) + goto fail; + + for (i = 0; i < num_msg; ++i) + { + info_msg = prompt = NULL; + + /* See if there is a following message that can be shown at the same + * time */ + if (auth_msgs[i].type == AUTH_MSGTYPE_INFO + && i+1 < num_msg + && ( auth_msgs[i+1].type == AUTH_MSGTYPE_PROMPT_NOECHO + || auth_msgs[i+1].type == AUTH_MSGTYPE_PROMPT_ECHO) + ) + { + info_msg = auth_msgs[i].msg; + prompt = auth_msgs[++i].msg; + } + else + { + if ( auth_msgs[i].type == AUTH_MSGTYPE_INFO + || auth_msgs[i].type == AUTH_MSGTYPE_ERROR) + info_msg = auth_msgs[i].msg; + else + prompt = auth_msgs[i].msg; + } + + { + char *info_msg_trimmed, *prompt_trimmed; + + /* Trailing whitespace looks bad in a GUI */ + info_msg_trimmed = remove_trailing_whitespace(info_msg); + prompt_trimmed = remove_trailing_whitespace(prompt); + + if (make_passwd_window(si, info_msg_trimmed, prompt_trimmed, + auth_msgs[i].type == AUTH_MSGTYPE_PROMPT_ECHO + ? True : False) + < 0) + goto fail; + + if (info_msg_trimmed) + free(info_msg_trimmed); + + if (prompt_trimmed) + free(prompt_trimmed); + } + + compose_status = calloc (1, sizeof (*compose_status)); + if (!compose_status) + goto fail; + + si->unlock_state = ul_read; + + handle_typeahead (si); + passwd_event_loop (si); + + if (si->unlock_state == ul_cancel) + goto fail; + + responses[i].response = strdup(si->pw_data->typed_passwd); + + /* Cache the first response to a PROMPT_NOECHO to save prompting for + * each auth mechanism. */ + if (si->cached_passwd == NULL && + auth_msgs[i].type == AUTH_MSGTYPE_PROMPT_NOECHO) + si->cached_passwd = strdup(responses[i].response); + + free (compose_status); + compose_status = 0; + } + + *resp = responses; + + return (si->unlock_state == ul_finished) ? 0 : -1; + +fail: + if (compose_status) + free (compose_status); + compose_status = 0; + + if (responses) + { + for (i = 0; i < num_msg; ++i) + if (responses[i].response) + free (responses[i].response); + free (responses); + } + + return -1; +} + + +void +auth_finished_cb (saver_info *si) +{ + char buf[1024]; + const char *s; + + /* If we have something to say, put the dialog back up for a few seconds + to display it. Otherwise, don't bother. + */ + + if (si->unlock_state == ul_fail && /* failed with caps lock on */ + si->pw_data && si->pw_data->caps_p) + s = "Authentication failed (Caps Lock?)"; + else if (si->unlock_state == ul_fail) /* failed without caps lock */ + s = "Authentication failed!"; + else if (si->unlock_state == ul_success && /* good, but report failures */ + si->unlock_failures > 0) + { + if (si->unlock_failures == 1) + s = "There has been\n1 failed login attempt."; + else + { + sprintf (buf, "There have been\n%d failed login attempts.", + si->unlock_failures); + s = buf; + } + si->unlock_failures = 0; + } + else /* good, with no failures, */ + goto END; /* or timeout, or cancel. */ + + make_passwd_window (si, s, NULL, True); + XSync (si->dpy, False); + + { + int secs = 4; + time_t start = time ((time_t *) 0); + XEvent event; + while (time ((time_t *) 0) < start + secs) + if (XPending (si->dpy)) + { + XNextEvent (si->dpy, &event); + if (event.xany.window == si->passwd_dialog && + event.xany.type == Expose) + draw_passwd_window (si); + else if (event.xany.type == ButtonPress || + event.xany.type == KeyPress) + break; + XSync (si->dpy, False); + } + else + usleep (250000); /* 1/4 second */ + } + + END: + if (si->pw_data) + destroy_passwd_window (si); +} + + +Bool +unlock_p (saver_info *si) +{ + saver_preferences *p = &si->prefs; + + if (!si->unlock_cb) + { + fprintf(stderr, "%s: Error: no unlock function specified!\n", blurb()); + return False; + } + + raise_window (si, True, True, True); + + xss_authenticate(si, p->verbose_p); + + return (si->unlock_state == ul_success); +} + + +void +set_locked_p (saver_info *si, Bool locked_p) +{ + si->locked_p = locked_p; + +#ifdef HAVE_XHPDISABLERESET + hp_lock_reset (si, locked_p); /* turn off/on C-Sh-Reset */ +#endif +#ifdef HAVE_XF86VMODE + xfree_lock_mode_switch (si, locked_p); /* turn off/on C-Alt-Plus */ +#endif +#ifdef HAVE_XF86MISCSETGRABKEYSSTATE + xfree_lock_grab_smasher (si, locked_p); /* turn off/on C-Alt-KP-*,/ */ +#endif + + store_saver_status (si); /* store locked-p */ +} + + +#else /* NO_LOCKING -- whole file */ + +void +set_locked_p (saver_info *si, Bool locked_p) +{ + if (locked_p) abort(); +} + +#endif /* !NO_LOCKING */ diff --git a/driver/mlstring.c b/driver/mlstring.c new file mode 100644 index 00000000..fdba1ee5 --- /dev/null +++ b/driver/mlstring.c @@ -0,0 +1,229 @@ +/* + * (c) 2007, Quest Software, Inc. All rights reserved. + * + * This file is part of XScreenSaver, + * Copyright (c) 1993-2009 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. + */ + +#include +#include + +#include + +#include "mlstring.h" + +#define LINE_SPACING 1.2 + +static mlstring * +mlstring_allocate(const char *msg); + +static void +mlstring_calculate(mlstring *str, XFontStruct *font); + +mlstring* +mlstring_new(const char *msg, XFontStruct *font, Dimension wrap_width) +{ + mlstring *newstr; + + if (!(newstr = mlstring_allocate(msg))) + return NULL; + + newstr->font_id = font->fid; + + mlstring_wrap(newstr, font, wrap_width); + + return newstr; +} + +mlstring * +mlstring_allocate(const char *msg) +{ + const char *s; + mlstring *ml; + struct mlstr_line *cur, *prev = NULL; + size_t linelength; + int the_end = 0; + + if (!msg) + return NULL; + + ml = calloc(1, sizeof(mlstring)); + + if (!ml) + return NULL; + + for (s = msg; !the_end; msg = ++s) + { + /* New string struct */ + cur = calloc(1, sizeof(struct mlstr_line)); + if (!cur) + goto fail; + + if (!ml->lines) + ml->lines = cur; + + /* Find the \n or end of string */ + while (*s != '\n') + { + if (*s == '\0') + { + the_end = 1; + break; + } + + ++s; + } + + linelength = s - msg; + + /* Duplicate the string */ + cur->line = malloc(linelength + 1); + if (!cur->line) + goto fail; + + strncpy(cur->line, msg, linelength); + cur->line[linelength] = '\0'; + + if (prev) + prev->next_line = cur; + prev = cur; + } + + return ml; + +fail: + + if (ml) + mlstring_free(ml); + + return NULL; +} + + +/* + * Frees an mlstring. + * This function does not have any unit tests. + */ +void +mlstring_free(mlstring *str) { + struct mlstr_line *cur, *next; + + for (cur = str->lines; cur; cur = next) { + next = cur->next_line; + free(cur->line); + free(cur); + } + + free(str); +} + + +void +mlstring_wrap(mlstring *mstring, XFontStruct *font, Dimension width) +{ + short char_width = font->max_bounds.width; + int line_length, wrap_at; + struct mlstr_line *mstr, *newml; + + /* An alternative implementation of this function would be to keep trying + * XTextWidth() on space-delimited substrings until the longest one less + * than 'width' is found, however there shouldn't be much difference + * between that, and this implementation. + */ + + for (mstr = mstring->lines; mstr; mstr = mstr->next_line) + { + if (XTextWidth(font, mstr->line, strlen(mstr->line)) > width) + { + /* Wrap it */ + line_length = width / char_width; + if (line_length == 0) + line_length = 1; + + /* First try to soft wrap by finding a space */ + for (wrap_at = line_length; wrap_at >= 0 && !isspace(mstr->line[wrap_at]); --wrap_at); + + if (wrap_at == -1) /* No space found, hard wrap */ + wrap_at = line_length; + else + wrap_at++; /* Leave the space at the end of the line. */ + + newml = calloc(1, sizeof(*newml)); + if (!newml) /* OOM, don't bother trying to wrap */ + break; + + if (NULL == (newml->line = strdup(mstr->line + wrap_at))) + { + /* OOM, jump ship */ + free(newml); + break; + } + + /* Terminate the existing string at its end */ + mstr->line[wrap_at] = '\0'; + + newml->next_line = mstr->next_line; + mstr->next_line = newml; + } + } + + mlstring_calculate(mstring, font); +} + +#undef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + +/* + * Calculates the overall extents (width + height of the multi-line string). + * This function is called as part of mlstring_new(). + * It does not have any unit testing. + */ +void +mlstring_calculate(mlstring *str, XFontStruct *font) { + struct mlstr_line *line; + + str->font_height = font->ascent + font->descent; + str->overall_height = 0; + str->overall_width = 0; + + /* XXX: Should there be some baseline calculations to help XDrawString later on? */ + str->font_ascent = font->ascent; + + for (line = str->lines; line; line = line->next_line) + { + line->line_width = XTextWidth(font, line->line, strlen(line->line)); + str->overall_width = MAX(str->overall_width, line->line_width); + /* Don't add line spacing for the first line */ + str->overall_height += (font->ascent + font->descent) * + (line == str->lines ? 1 : LINE_SPACING); + } +} + +void +mlstring_draw(Display *dpy, Drawable dialog, GC gc, mlstring *string, int x, int y) { + struct mlstr_line *line; + + if (!string) + return; + + y += string->font_ascent; + + XSetFont(dpy, gc, string->font_id); + + for (line = string->lines; line; line = line->next_line) + { + XDrawString(dpy, dialog, gc, x, y, line->line, strlen(line->line)); + y += string->font_height * LINE_SPACING; + } +} + +/* vim:ts=8:sw=2:noet + */ diff --git a/driver/mlstring.h b/driver/mlstring.h new file mode 100644 index 00000000..ce362056 --- /dev/null +++ b/driver/mlstring.h @@ -0,0 +1,57 @@ +/* mlstring.h --- Multi-line strings for use with Xlib + * + * (c) 2007, Quest Software, Inc. All rights reserved. + * + * This file is part of XScreenSaver, + * Copyright (c) 1993-2004 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 MLSTRING_H +#define MLSTRING_H + +#include + +/* mlstring means multi-line string */ + +struct mlstr_line; + +typedef struct mlstring mlstring; +struct mlstring { + struct mlstr_line *lines; /* linked list */ + Dimension overall_height; + Dimension overall_width; + /* XXX: Perhaps it is simpler to keep a reference to the XFontStruct */ + int font_ascent; + int font_height; + Font font_id; +}; + +struct mlstr_line { + char *line; + Dimension line_width; + struct mlstr_line *next_line; +}; + +mlstring * +mlstring_new(const char *str, XFontStruct *font, Dimension wrap_width); + +/* Does not have to be called manually */ +void +mlstring_wrap(mlstring *mstr, XFontStruct *font, Dimension width); + +void +mlstring_free(mlstring *str); + +void +mlstring_draw(Display *dpy, Drawable dialog, GC gc, mlstring *string, int x, int y); + +#endif +/* vim:ts=8:sw=2:noet + */ diff --git a/driver/passwd-helper.c b/driver/passwd-helper.c new file mode 100644 index 00000000..a3a6b924 --- /dev/null +++ b/driver/passwd-helper.c @@ -0,0 +1,162 @@ +/* passwd-helper.c --- verifying typed passwords with external helper program + * written by Olaf Kirch + * xscreensaver, Copyright (c) 1993-2005 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. + */ + +/* The idea here is to be able to run xscreensaver without any setuid bits. + * Password verification happens through an external program that you feed + * your password to on stdin. The external command is invoked with a user + * name argument. + * + * The external helper does whatever authentication is necessary. Currently, + * SuSE uses "unix2_chkpwd", which is a variation of "unix_chkpwd" from the + * PAM distribution. + * + * Normally, the password helper should just authenticate the calling user + * (i.e. based on the caller's real uid). This is in order to prevent + * brute-forcing passwords in a shadow environment. A less restrictive + * approach would be to allow verifying other passwords as well, but always + * with a 2 second delay or so. (Not sure what SuSE's "unix2_chkpwd" + * currently does.) + * -- Olaf Kirch , 16-Dec-2003 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include /* not used for much... */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +static int +ext_run (const char *user, const char *typed_passwd, int verbose_p) +{ + int pfd[2], status; + pid_t pid; + + if (pipe(pfd) < 0) + return 0; + + if (verbose_p) + fprintf (stderr, "%s: ext_run (%s, %s)\n", + blurb(), PASSWD_HELPER_PROGRAM, user); + + block_sigchld(); + + if ((pid = fork()) < 0) { + close(pfd[0]); + close(pfd[1]); + return 0; + } + + if (pid == 0) { + close(pfd[1]); + if (pfd[0] != 0) + dup2(pfd[0], 0); + + /* Helper is invoked as helper service-name [user] */ + execlp(PASSWD_HELPER_PROGRAM, PASSWD_HELPER_PROGRAM, "xscreensaver", user, NULL); + if (verbose_p) + fprintf(stderr, "%s: %s\n", PASSWD_HELPER_PROGRAM, + strerror(errno)); + exit(1); + } + + close(pfd[0]); + + /* Write out password to helper process */ + if (!typed_passwd) + typed_passwd = ""; + write(pfd[1], typed_passwd, strlen(typed_passwd)); + close(pfd[1]); + + while (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) + continue; + if (verbose_p) + fprintf(stderr, "%s: ext_run: waitpid failed: %s\n", + blurb(), strerror(errno)); + unblock_sigchld(); + return 0; + } + + unblock_sigchld(); + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return 0; + return 1; +} + + + +/* This can be called at any time, and says whether the typed password + belongs to either the logged in user (real uid, not effective); or + to root. + */ +int +ext_passwd_valid_p (const char *typed_passwd, int verbose_p) +{ + struct passwd *pw; + int res = 0; + + if ((pw = getpwuid(getuid())) != NULL) + res = ext_run (pw->pw_name, typed_passwd, verbose_p); + endpwent(); + +#ifdef ALLOW_ROOT_PASSWD + if (!res) + res = ext_run ("root", typed_passwd, verbose_p); +#endif /* ALLOW_ROOT_PASSWD */ + + return res; +} + + +int +ext_priv_init (int argc, char **argv, int verbose_p) +{ + /* Make sure the passwd helper exists */ + if (access(PASSWD_HELPER_PROGRAM, X_OK) < 0) { + fprintf(stderr, + "%s: warning: %s does not exist.\n" + "%s: password authentication via " + "external helper will not work.\n", + blurb(), PASSWD_HELPER_PROGRAM, blurb()); + return 0; + } + return 1; +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd-kerberos.c b/driver/passwd-kerberos.c new file mode 100644 index 00000000..202e0eb1 --- /dev/null +++ b/driver/passwd-kerberos.c @@ -0,0 +1,251 @@ +/* kpasswd.c --- verify kerberos passwords. + * written by Nat Lanza (magus@cs.cmu.edu) for + * xscreensaver, Copyright (c) 1993-2004 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include + +/* I'm not sure if this is exactly the right test... + Might __APPLE__ be defined if this is apple hardware, but not + an Apple OS? + + Thanks to Alexei Kosut for the MacOS X code. + */ +#ifdef __APPLE__ +# define HAVE_DARWIN +#endif + + +#if defined(HAVE_DARWIN) +# include +#elif defined(HAVE_KERBEROS5) +# include +# include +#else /* !HAVE_KERBEROS5 (meaning Kerberos 4) */ +# include +# include +#endif /* !HAVE_KERBEROS5 */ + +#if !defined(VMS) && !defined(HAVE_ADJUNCT_PASSWD) +# include +#endif + + +#ifdef __bsdi__ +# include +# if _BSDI_VERSION >= 199608 +# define BSD_AUTH +# endif +#endif /* __bsdi__ */ + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +/* The user information we need to store */ +#ifdef HAVE_DARWIN + static KLPrincipal princ; +#else /* !HAVE_DARWIN */ + static char realm[REALM_SZ]; + static char name[ANAME_SZ]; + static char inst[INST_SZ]; + static const char *tk_file; +#endif /* !HAVE_DARWIN */ + +/* warning suppression: duplicated in passwd.c */ +extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p); +extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p); + + +/* Called at startup to grab user, instance, and realm information + from the user's ticketfile (remember, name.inst@realm). Since we're + using tf_get_pname(), this should work even if your kerberos username + isn't the same as your local username. We grab the ticket at startup + time so that even if your ticketfile dies while the screen's locked + we'll still have the information to unlock it. + + Problems: the password dialog currently displays local username, so if + you have some non-standard name/instance when you run xscreensaver, + you'll need to remember what it was when unlocking, or else you lose. + + Also, we use des_string_to_key(), so if you have an AFS password + (encrypted with ka_StringToKey()), you'll lose. Get a kerberos password; + it isn't that hard. + + Like the original lock_init, we return false if something went wrong. + We don't use the arguments we're given, though. + */ +Bool +kerberos_lock_init (int argc, char **argv, Bool verbose_p) +{ +# ifdef HAVE_DARWIN + + KLBoolean found; + return ((klNoErr == (KLCacheHasValidTickets (NULL, kerberosVersion_Any, + &found, &princ, NULL))) + && found); + +# else /* !HAVE_DARWIN */ + + /* Perhaps we should be doing it the Mac way (above) all the time? + The following code assumes Unix-style file-based Kerberos credentials + cache, which Mac OS X doesn't use. But is there any real reason to + do it this way at all, even on other Unixen? + */ + int k_errno; + + memset(name, 0, sizeof(name)); + memset(inst, 0, sizeof(inst)); + + /* find out where the user's keeping his tickets. + squirrel it away for later use. */ + tk_file = tkt_string(); + + /* open ticket file or die trying. */ + if ((k_errno = tf_init(tk_file, R_TKT_FIL))) { + return False; + } + + /* same with principal and instance names */ + if ((k_errno = tf_get_pname(name)) || + (k_errno = tf_get_pinst(inst))) { + return False; + } + + /* close the ticketfile to release the lock on it. */ + tf_close(); + + /* figure out what realm we're authenticated to. this ought + to be the local realm, but it pays to be sure. */ + if ((k_errno = krb_get_tf_realm(tk_file, realm))) { + return False; + } + + /* last-minute sanity check on what we got. */ + if ((strlen(name)+strlen(inst)+strlen(realm)+3) > + (REALM_SZ + ANAME_SZ + INST_SZ + 3)) { + return False; + } + + /* success */ + return True; + +# endif /* !HAVE_DARWIN */ +} + + +/* des_string_to_key() wants this. If C didn't suck, we could have an + anonymous function do this. Even a local one. But it does, so here + we are. Calling it ive_got_your_local_function_right_here_buddy() + would have been rude. + */ +#ifndef HAVE_DARWIN +static int +key_to_key(char *user, char *instance, char *realm, char *passwd, C_Block key) +{ + memcpy(key, passwd, sizeof(des_cblock)); + return (0); +} +#endif /* !HAVE_DARWIN */ + +/* Called to see if the user's typed password is valid. We do this by asking + the kerberos server for a ticket and checking to see if it gave us one. + We need to move the ticketfile first, or otherwise we end up updating the + user's tkfile with new tickets. This would break services like zephyr that + like to stay authenticated, and it would screw with AFS authentication at + some sites. So, we do a quick, painful hack with a tmpfile. + */ +Bool +kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p) +{ +# ifdef HAVE_DARWIN + return (klNoErr == + KLAcquireNewInitialTicketsWithPassword (princ, NULL, + typed_passwd, NULL)); +# else /* !HAVE_DARWIN */ + + /* See comments in kerberos_lock_init -- should we do it the Mac Way + on all systems? + */ + C_Block mitkey; + Bool success; + char *newtkfile; + int fh = -1; + + /* temporarily switch to a new ticketfile. + I'm not using tmpnam() because it isn't entirely portable. + this could probably be fixed with autoconf. */ + newtkfile = malloc(80 * sizeof(char)); + memset(newtkfile, 0, sizeof(newtkfile)); + + sprintf(newtkfile, "/tmp/xscrn-%i.XXXXXX", getpid()); + + if( (fh = mkstemp(newtkfile)) < 0) + { + free(newtkfile); + return(False); + } + if( fchmod(fh, 0600) < 0) + { + free(newtkfile); + return(False); + } + + + krb_set_tkt_string(newtkfile); + + /* encrypt the typed password. if you have an AFS password instead + of a kerberos one, you lose *right here*. If you want to use AFS + passwords, you can use ka_StringToKey() instead. As always, ymmv. */ + des_string_to_key(typed_passwd, mitkey); + + if (krb_get_in_tkt(name, inst, realm, "krbtgt", realm, DEFAULT_TKT_LIFE, + key_to_key, NULL, (char *) mitkey) != 0) { + success = False; + } else { + success = True; + } + + /* quickly block out the tempfile and password to prevent snooping, + then restore the old ticketfile and cleean up a bit. */ + + dest_tkt(); + krb_set_tkt_string(tk_file); + free(newtkfile); + memset(mitkey, 0, sizeof(mitkey)); + close(fh); /* #### tom: should the file be removed? */ + + + /* Did we verify successfully? */ + return success; + +# endif /* !HAVE_DARWIN */ +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd-pam.c b/driver/passwd-pam.c new file mode 100644 index 00000000..0c60d508 --- /dev/null +++ b/driver/passwd-pam.c @@ -0,0 +1,514 @@ +/* passwd-pam.c --- verifying typed passwords with PAM + * (Pluggable Authentication Modules.) + * written by Bill Nottingham (and jwz) for + * xscreensaver, Copyright (c) 1993-2012 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. + * + * Some PAM resources: + * + * PAM home page: + * http://www.us.kernel.org/pub/linux/libs/pam/ + * + * PAM FAQ: + * http://www.us.kernel.org/pub/linux/libs/pam/FAQ + * + * PAM Application Developers' Guide: + * http://www.us.kernel.org/pub/linux/libs/pam/Linux-PAM-html/Linux-PAM_ADG.html + * + * PAM Mailing list archives: + * http://www.linuxhq.com/lnxlists/linux-pam/ + * + * Compatibility notes, especially between Linux and Solaris: + * http://www.contrib.andrew.cmu.edu/u/shadow/pam.html + * + * The Open Group's PAM API documentation: + * http://www.opengroup.org/onlinepubs/8329799/pam_start.htm + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +extern char *blurb(void); + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "auth.h" + +extern sigset_t block_sigchld (void); +extern void unblock_sigchld (void); + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +#undef countof +#define countof(x) (sizeof((x))/sizeof(*(x))) + +/* Some time between Red Hat 4.2 and 7.0, the words were transposed + in the various PAM_x_CRED macro names. Yay! + */ +#ifndef PAM_REFRESH_CRED +# define PAM_REFRESH_CRED PAM_CRED_REFRESH +#endif + +static int pam_conversation (int nmsgs, + const struct pam_message **msg, + struct pam_response **resp, + void *closure); + +void pam_try_unlock(saver_info *si, Bool verbose_p, + Bool (*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.*/ + /* Don't set this to 0 (Linux bug workaround.) */ +# define PAM_NO_DELAY(pamh) pam_fail_delay ((pamh), 1) +#else /* !HAVE_PAM_FAIL_DELAY */ +# define PAM_NO_DELAY(pamh) /* */ +#endif /* !HAVE_PAM_FAIL_DELAY */ + + +/* On SunOS 5.6, and on Linux with PAM 0.64, pam_strerror() takes two args. + On some other Linux systems with some other version of PAM (e.g., + whichever Debian release comes with a 2.2.5 kernel) it takes one arg. + I can't tell which is more "recent" or "correct" behavior, so configure + figures out which is in use for us. Shoot me! + */ +#ifdef PAM_STRERROR_TWO_ARGS +# define PAM_STRERROR(pamh, status) pam_strerror((pamh), (status)) +#else /* !PAM_STRERROR_TWO_ARGS */ +# define PAM_STRERROR(pamh, status) pam_strerror((status)) +#endif /* !PAM_STRERROR_TWO_ARGS */ + + +/* PAM sucks in that there is no way to tell whether a particular service + is configured at all. That is, there is no way to tell the difference + between "authentication of the FOO service is not allowed" and "the + user typed the wrong password." + + On RedHat 5.1 systems, if a service name is not known, it defaults to + being not allowed (because the fallback service, /etc/pam.d/other, is + set to `pam_deny'.) + + On Solaris 2.6 systems, unknown services default to authenticating normally. + + So, we could simply require that the person who installs xscreensaver + set up an "xscreensaver" PAM service. However, if we went that route, + it would have a really awful failure mode: the failure mode would be that + xscreensaver was willing to *lock* the screen, but would be unwilling to + *unlock* the screen. (With the non-PAM password code, the analagous + situation -- security not being configured properly, for example do to the + executable not being installed as setuid root -- the failure mode is much + more palettable, in that xscreensaver will refuse to *lock* the screen, + because it can know up front that there is no password that will work.) + + Another route would be to have the service name to consult be computed at + compile-time (perhaps with a configure option.) However, that doesn't + really solve the problem, because it means that the same executable might + work fine on one machine, but refuse to unlock when run on another + machine. + + Another alternative would be to look in /etc/pam.conf or /etc/pam.d/ at + runtime to see what services actually exist. But I think that's no good, + because who is to say that the PAM info is actually specified in those + files? Opening and reading those files is not a part of the PAM client + API, so it's not guarenteed to work on any given system. + + An alternative I tried was to specify a list of services to try, and to + try them all in turn ("xscreensaver", "xlock", "xdm", and "login"). + This worked, but it was slow (and I also had to do some contortions to + work around bugs in Linux PAM 0.64-3.) + + So what we do today is, try PAM once, and if that fails, try the usual + getpwent() method. So if PAM doesn't work, it will at least make an + attempt at looking up passwords in /etc/passwd or /etc/shadow instead. + + This all kind of blows. I'm not sure what else to do. + */ + + +/* On SunOS 5.6, the `pam_conv.appdata_ptr' slot seems to be ignored, and + the `closure' argument to pc.conv always comes in as random garbage. + So we get around this by using a global variable instead. Shoot me! + + (I've been told this is bug 4092227, and is fixed in Solaris 7.) + (I've also been told that it's fixed in Solaris 2.6 by patch 106257-05.) + */ +static void *suns_pam_implementation_blows = 0; + + +/** + * This function is the PAM conversation driver. It conducts a full + * authentication round by invoking the GUI with various prompts. + */ +void +pam_try_unlock(saver_info *si, Bool verbose_p, + Bool (*valid_p)(const char *typed_passwd, Bool verbose_p)) +{ + const char *service = PAM_SERVICE_NAME; + pam_handle_t *pamh = 0; + int status = -1; + struct pam_conv pc; + sigset_t set; + struct timespec timeout; + + pc.conv = &pam_conversation; + pc.appdata_ptr = (void *) si; + + /* On SunOS 5.6, the `appdata_ptr' slot seems to be ignored, and the + `closure' argument to pc.conv always comes in as random garbage. */ + suns_pam_implementation_blows = (void *) si; + + + /* Initialize PAM. + */ + status = pam_start (service, si->user, &pc, &pamh); + if (verbose_p) + fprintf (stderr, "%s: pam_start (\"%s\", \"%s\", ...) ==> %d (%s)\n", + blurb(), service, si->user, + status, PAM_STRERROR (pamh, status)); + if (status != PAM_SUCCESS) goto DONE; + + /* #### We should set PAM_TTY to the display we're using, but we + don't have that handy from here. So set it to :0.0, which is a + good guess (and has the bonus of counting as a "secure tty" as + far as PAM is concerned...) + */ + { + char *tty = strdup (":0.0"); + status = pam_set_item (pamh, PAM_TTY, tty); + if (verbose_p) + fprintf (stderr, "%s: pam_set_item (p, PAM_TTY, \"%s\") ==> %d (%s)\n", + blurb(), tty, status, PAM_STRERROR(pamh, status)); + free (tty); + } + + /* Try to authenticate as the current user. + We must turn off our SIGCHLD handler for the duration of the call to + pam_authenticate(), because in some cases, the underlying PAM code + will do this: + + 1: fork a setuid subprocess to do some dirty work; + 2: read a response from that subprocess; + 3: waitpid(pid, ...) on that subprocess. + + If we (the ignorant parent process) have a SIGCHLD handler, then there's + a race condition between steps 2 and 3: if the subprocess exits before + waitpid() was called, then our SIGCHLD handler fires, and gets notified + of the subprocess death; then PAM's call to waitpid() fails, because the + process has already been reaped. + + I consider this a bug in PAM, since the caller should be able to have + whatever signal handlers it wants -- the PAM documentation doesn't say + "oh by the way, if you use PAM, you can't use SIGCHLD." + */ + + PAM_NO_DELAY(pamh); + + if (verbose_p) + fprintf (stderr, "%s: pam_authenticate (...) ...\n", blurb()); + + timeout.tv_sec = 0; + timeout.tv_nsec = 1; + set = block_sigchld(); + status = pam_authenticate (pamh, 0); +# ifdef HAVE_SIGTIMEDWAIT + sigtimedwait (&set, NULL, &timeout); + /* #### What is the portable thing to do if we don't have it? */ +# endif /* HAVE_SIGTIMEDWAIT */ + unblock_sigchld(); + + if (verbose_p) + fprintf (stderr, "%s: pam_authenticate (...) ==> %d (%s)\n", + blurb(), status, PAM_STRERROR(pamh, status)); + + if (status == PAM_SUCCESS) /* Win! */ + { + int status2; + + /* On most systems, it doesn't matter whether the account modules + are run, or whether they fail or succeed. + + On some systems, the account modules fail, because they were + never configured properly, but it's necessary to run them anyway + because certain PAM modules depend on side effects of the account + modules having been run. + + And on still other systems, the account modules are actually + used, and failures in them should be considered to be true! + + So: + - We run the account modules on all systems. + - Whether we ignore them is a configure option. + + It's all kind of a mess. + */ + status2 = pam_acct_mgmt (pamh, 0); + + if (verbose_p) + fprintf (stderr, "%s: pam_acct_mgmt (...) ==> %d (%s)\n", + blurb(), status2, PAM_STRERROR(pamh, status2)); + + /* HPUX for some reason likes to make PAM defines different from + * everyone else's. */ +#ifdef PAM_AUTHTOKEN_REQD + if (status2 == PAM_AUTHTOKEN_REQD) +#else + if (status2 == PAM_NEW_AUTHTOK_REQD) +#endif + { + status2 = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + if (verbose_p) + fprintf (stderr, "%s: pam_chauthtok (...) ==> %d (%s)\n", + blurb(), status2, PAM_STRERROR(pamh, status2)); + } + + /* If 'configure' requested that we believe the results of PAM + account module failures, then obey that status code. + Otherwise ignore it. + */ +#ifdef PAM_CHECK_ACCOUNT_TYPE + status = status2; +#endif + + /* Each time we successfully authenticate, refresh credentials, + for Kerberos/AFS/DCE/etc. If this fails, just ignore that + failure and blunder along; it shouldn't matter. + + Note: this used to be PAM_REFRESH_CRED instead of + PAM_REINITIALIZE_CRED, but Jason Heiss + says that the Linux PAM library ignores that one, and only refreshes + credentials when using PAM_REINITIALIZE_CRED. + */ + status2 = pam_setcred (pamh, PAM_REINITIALIZE_CRED); + if (verbose_p) + fprintf (stderr, "%s: pam_setcred (...) ==> %d (%s)\n", + blurb(), status2, PAM_STRERROR(pamh, status2)); + } + + DONE: + if (pamh) + { + int status2 = pam_end (pamh, status); + pamh = 0; + if (verbose_p) + fprintf (stderr, "%s: pam_end (...) ==> %d (%s)\n", + blurb(), status2, + (status2 == PAM_SUCCESS ? "Success" : "Failure")); + } + + if (status == PAM_SUCCESS) + si->unlock_state = ul_success; /* yay */ + else if (si->unlock_state == ul_cancel || + si->unlock_state == ul_time) + ; /* more specific failures ok */ + else + si->unlock_state = ul_fail; /* generic failure */ +} + + +Bool +pam_priv_init (int argc, char **argv, Bool verbose_p) +{ + /* We have nothing to do at init-time. + However, we might as well do some error checking. + If "/etc/pam.d" exists and is a directory, but "/etc/pam.d/xlock" + does not exist, warn that PAM probably isn't going to work. + + This is a priv-init instead of a non-priv init in case the directory + is unreadable or something (don't know if that actually happens.) + */ + const char dir[] = "/etc/pam.d"; + const char file[] = "/etc/pam.d/" PAM_SERVICE_NAME; + const char file2[] = "/etc/pam.conf"; + struct stat st; + +# ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +# endif + + if (stat (dir, &st) == 0 && S_ISDIR(st.st_mode)) + { + if (stat (file, &st) != 0) + fprintf (stderr, + "%s: warning: %s does not exist.\n" + "%s: password authentication via PAM is unlikely to work.\n", + blurb(), file, blurb()); + } + else if (stat (file2, &st) == 0) + { + FILE *f = fopen (file2, "r"); + if (f) + { + Bool ok = False; + char buf[255]; + while (fgets (buf, sizeof(buf), f)) + if (strstr (buf, PAM_SERVICE_NAME)) + { + ok = True; + break; + } + fclose (f); + if (!ok) + { + fprintf (stderr, + "%s: warning: %s does not list the `%s' service.\n" + "%s: password authentication via PAM is unlikely to work.\n", + blurb(), file2, PAM_SERVICE_NAME, blurb()); + } + } + /* else warn about file2 existing but being unreadable? */ + } + else + { + fprintf (stderr, + "%s: warning: neither %s nor %s exist.\n" + "%s: password authentication via PAM is unlikely to work.\n", + blurb(), file2, file, blurb()); + } + + /* Return true anyway, just in case. */ + return True; +} + + +static int +pam_conversation (int nmsgs, + const struct pam_message **msg, + struct pam_response **resp, + void *vsaver_info) +{ + int i, ret = -1; + struct auth_message *messages = 0; + struct auth_response *authresp = 0; + struct pam_response *pam_responses; + saver_info *si = (saver_info *) vsaver_info; + Bool verbose_p; + + /* On SunOS 5.6, the `closure' argument always comes in as random garbage. */ + si = (saver_info *) suns_pam_implementation_blows; + + verbose_p = si->prefs.verbose_p; + + /* Converting the PAM prompts into the XScreenSaver native format. + * It was a design goal to collapse (INFO,PROMPT) pairs from PAM + * into a single call to the unlock_cb function. The unlock_cb function + * does that, but only if it is passed several prompts at a time. Most PAM + * modules only send a single prompt at a time, but because there is no way + * of telling whether there will be more prompts to follow, we can only ever + * pass along whatever was passed in here. + */ + + messages = calloc(nmsgs, sizeof(struct auth_message)); + pam_responses = calloc(nmsgs, sizeof(*pam_responses)); + + if (!pam_responses || !messages) + goto end; + + if (verbose_p) + fprintf (stderr, "%s: pam_conversation (", blurb()); + + for (i = 0; i < nmsgs; ++i) + { + if (verbose_p && i > 0) fprintf (stderr, ", "); + + messages[i].msg = msg[i]->msg; + + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_OFF: messages[i].type = AUTH_MSGTYPE_PROMPT_NOECHO; + if (verbose_p) fprintf (stderr, "ECHO_OFF"); + break; + case PAM_PROMPT_ECHO_ON: messages[i].type = AUTH_MSGTYPE_PROMPT_ECHO; + if (verbose_p) fprintf (stderr, "ECHO_ON"); + break; + case PAM_ERROR_MSG: messages[i].type = AUTH_MSGTYPE_ERROR; + if (verbose_p) fprintf (stderr, "ERROR_MSG"); + break; + case PAM_TEXT_INFO: messages[i].type = AUTH_MSGTYPE_INFO; + if (verbose_p) fprintf (stderr, "TEXT_INFO"); + break; + default: messages[i].type = AUTH_MSGTYPE_PROMPT_ECHO; + if (verbose_p) fprintf (stderr, "PROMPT_ECHO"); + break; + } + + if (verbose_p) + fprintf (stderr, "=\"%s\"", msg[i]->msg ? msg[i]->msg : "(null)"); + } + + if (verbose_p) + fprintf (stderr, ") ...\n"); + + ret = si->unlock_cb(nmsgs, messages, &authresp, si); + + /* #### If the user times out, or hits ESC or Cancel, we return PAM_CONV_ERR, + and PAM logs this as an authentication failure. It would be nice if + there was some way to indicate that this was a "cancel" rather than + a "fail", so that it wouldn't show up in syslog, but I think the + only options are PAM_SUCCESS and PAM_CONV_ERR. (I think that + PAM_ABORT means "internal error", not "cancel".) Bleh. + */ + + if (ret == 0) + { + for (i = 0; i < nmsgs; ++i) + pam_responses[i].resp = authresp[i].response; + } + +end: + if (messages) + free(messages); + + if (authresp) + free(authresp); + + if (verbose_p) + fprintf (stderr, "%s: pam_conversation (...) ==> %s\n", blurb(), + (ret == 0 ? "PAM_SUCCESS" : "PAM_CONV_ERR")); + + if (ret == 0) + { + *resp = pam_responses; + return PAM_SUCCESS; + } + + /* Failure only */ + if (pam_responses) + free(pam_responses); + + return PAM_CONV_ERR; +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd-pwent.c b/driver/passwd-pwent.c new file mode 100644 index 00000000..bb0edfc2 --- /dev/null +++ b/driver/passwd-pwent.c @@ -0,0 +1,312 @@ +/* passwd-pwent.c --- verifying typed passwords with the OS. + * xscreensaver, Copyright (c) 1993-1998 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_CRYPT_H +# include +#endif + +#include +#include +#include +#ifndef VMS +# include +# include +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + + +#ifdef __bsdi__ +# include +# if _BSDI_VERSION >= 199608 +# define BSD_AUTH +# endif +#endif /* __bsdi__ */ + + +#if defined(HAVE_SHADOW_PASSWD) /* passwds live in /etc/shadow */ + +# include +# define PWTYPE struct spwd * +# define PWPSLOT sp_pwdp +# define GETPW getspnam + +#elif defined(HAVE_ENHANCED_PASSWD) /* passwds live in /tcb/files/auth/ */ + /* M.Matsumoto */ +# include +# include + +# define PWTYPE struct pr_passwd * +# define PWPSLOT ufld.fd_encrypt +# define GETPW getprpwnam + +#elif defined(HAVE_ADJUNCT_PASSWD) + +# include +# include +# include + +# define PWTYPE struct passwd_adjunct * +# define PWPSLOT pwa_passwd +# define GETPW getpwanam + +#elif defined(HAVE_HPUX_PASSWD) + +# include +# include + +# define PWTYPE struct s_passwd * +# define PWPSLOT pw_passwd +# define GETPW getspwnam + +# define HAVE_BIGCRYPT + +#endif + + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + + +extern const char *blurb(void); + +static char *encrypted_root_passwd = 0; +static char *encrypted_user_passwd = 0; + +#ifdef VMS +# define ROOT "SYSTEM" +#else +# 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 + +static char * +user_name (void) +{ + /* I think that just checking $USER here is not the best idea. */ + + const char *u = 0; + + /* It has been reported that getlogin() returns the wrong user id on some + very old SGI systems... And I've seen it return the string "rlogin" + sometimes! Screw it, using getpwuid() should be enough... + */ +/* u = (char *) getlogin (); + */ + + /* getlogin() fails if not attached to a terminal; in that case, use + getpwuid(). (Note that in this case, we're not doing shadow stuff, since + all we're interested in is the name, not the password. So that should + still work. Right?) */ + if (!u || !*u) + { + struct passwd *p = getpwuid (getuid ()); + u = (p ? p->pw_name : 0); + } + + return (u ? strdup(u) : 0); +} + +#else /* VMS */ + +static char * +user_name (void) +{ + char *u = getenv("USER"); + return (u ? strdup(u) : 0); +} + +#endif /* VMS */ + + +static Bool +passwd_known_p (const char *pw) +{ + return (pw && + pw[0] != '*' && /* This would be sensible... */ + strlen(pw) > 4); /* ...but this is what Solaris does. */ +} + + +static char * +get_encrypted_passwd(const char *user) +{ + char *result = 0; + +#ifdef PWTYPE + if (user && *user && !result) + { /* First check the shadow passwords. */ + PWTYPE p = GETPW((char *) user); + if (p && passwd_known_p (p->PWPSLOT)) + result = strdup(p->PWPSLOT); + } +#endif /* PWTYPE */ + + if (user && *user && !result) + { /* Check non-shadow passwords too. */ + struct passwd *p = getpwnam(user); + if (p && passwd_known_p (p->pw_passwd)) + result = strdup(p->pw_passwd); + } + + /* The manual for passwd(4) on HPUX 10.10 says: + + Password aging is put in effect for a particular user if his + encrypted password in the password file is followed by a comma and + a nonnull string of characters from the above alphabet. This + string defines the "age" needed to implement password aging. + + So this means that passwd->pw_passwd isn't simply a string of cyphertext, + it might have trailing junk. So, if there is a comma in the string, and + that comma is beyond position 13, terminate the string before the comma. + */ + if (result && strlen(result) > 13) + { + char *s = strchr (result+13, ','); + if (s) + *s = 0; + } + +#ifndef HAVE_PAM + /* We only issue this warning if not compiled with support for PAM. + If we're using PAM, it's not unheard of that normal pwent passwords + would be unavailable. */ + + if (!result) + fprintf (stderr, "%s: couldn't get password of \"%s\"\n", + blurb(), (user ? user : "(null)")); +#endif /* !HAVE_PAM */ + + return result; +} + + + +/* This has to be called before we've changed our effective user ID, + because it might need privileges to get at the encrypted passwords. + Returns false if we weren't able to get any passwords, and therefore, + locking isn't possible. (It will also have written to stderr.) + */ + +#ifndef VMS + +Bool +pwent_priv_init (int argc, char **argv, Bool verbose_p) +{ + char *u; + +#ifdef HAVE_ENHANCED_PASSWD + set_auth_parameters(argc, argv); + check_auth_parameters(); +#endif /* HAVE_DEC_ENHANCED */ + + u = user_name(); + encrypted_user_passwd = get_encrypted_passwd(u); + encrypted_root_passwd = get_encrypted_passwd(ROOT); + if (u) free (u); + + if (encrypted_user_passwd) + return True; + else + return False; +} + + +Bool +pwent_lock_init (int argc, char **argv, Bool verbose_p) +{ + if (encrypted_user_passwd) + return True; + else + return False; +} + + + +static Bool +passwds_match_p (const char *cleartext, const char *ciphertext) +{ + char *s = 0; /* note that on some systems, crypt() may return null */ + + s = (char *) crypt (cleartext, ciphertext); + if (s && !strcmp (s, ciphertext)) + return True; + +#ifdef HAVE_BIGCRYPT + /* There seems to be no way to tell at runtime if an HP machine is in + "trusted" mode, and thereby, which of crypt() or bigcrypt() we should + be calling to compare passwords. So call them both, and see which + one works. */ + + s = (char *) bigcrypt (cleartext, ciphertext); + if (s && !strcmp (s, ciphertext)) + return True; + +#endif /* HAVE_BIGCRYPT */ + + return False; +} + + + +/* This can be called at any time, and says whether the typed password + belongs to either the logged in user (real uid, not effective); or + to root. + */ +Bool +pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p) +{ + if (encrypted_user_passwd && + passwds_match_p (typed_passwd, encrypted_user_passwd)) + return True; + +#ifdef ALLOW_ROOT_PASSWD + /* do not allow root to have a null password. */ + else if (typed_passwd[0] && + encrypted_root_passwd && + passwds_match_p (typed_passwd, encrypted_root_passwd)) + return True; +#endif /* ALLOW_ROOT_PASSWD */ + + else + return False; +} + +#else /* VMS */ +Bool pwent_lock_init (int argc, char **argv, Bool verbose_p) { return True; } +#endif /* VMS */ + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/passwd.c b/driver/passwd.c new file mode 100644 index 00000000..fd42c552 --- /dev/null +++ b/driver/passwd.c @@ -0,0 +1,334 @@ +/* passwd.c --- verifying typed passwords with the OS. + * xscreensaver, Copyright (c) 1993-2004 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef NO_LOCKING /* whole file */ + +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifndef VMS +# include /* for getpwuid() */ +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + +#ifdef HAVE_SYSLOG +# include +#endif /* HAVE_SYSLOG */ + +#include + +#include "xscreensaver.h" +#include "auth.h" + +extern const char *blurb(void); +extern void check_for_leaks (const char *where); + + +/* blargh */ +#undef Bool +#undef True +#undef False +#define Bool int +#define True 1 +#define False 0 + +#undef countof +#define countof(x) (sizeof((x))/sizeof(*(x))) + +struct auth_methods { + const char *name; + Bool (*init) (int argc, char **argv, Bool verbose_p); + Bool (*priv_init) (int argc, char **argv, Bool verbose_p); + Bool (*valid_p) (const char *typed_passwd, Bool verbose_p); + void (*try_unlock) (saver_info *si, Bool verbose_p, + Bool (*valid_p)(const char *typed_passwd, Bool verbose_p)); + Bool initted_p; + Bool priv_initted_p; +}; + + +#ifdef HAVE_KERBEROS +extern Bool kerberos_lock_init (int argc, char **argv, Bool verbose_p); +extern Bool kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +#endif +#ifdef HAVE_PAM +extern Bool pam_priv_init (int argc, char **argv, Bool verbose_p); +extern void pam_try_unlock (saver_info *si, Bool verbose_p, + Bool (*valid_p)(const char *typed_passwd, Bool verbose_p)); +#endif +#ifdef PASSWD_HELPER_PROGRAM +extern Bool ext_priv_init (int argc, char **argv, Bool verbose_p); +extern Bool ext_passwd_valid_p (const char *typed_passwd, Bool verbose_p); +#endif +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, + since that code tries shadow passwords, and then non-shadow passwords. + (It's all in the same file since the APIs are randomly nearly-identical.) + */ +struct auth_methods methods[] = { +# ifdef HAVE_PAM + { "PAM", 0, pam_priv_init, 0, pam_try_unlock, + False, False }, +# endif +# ifdef HAVE_KERBEROS + { "Kerberos", kerberos_lock_init, 0, kerberos_passwd_valid_p, 0, + False, False }, +# endif +# ifdef PASSWD_HELPER_PROGRAM + { "external", 0, ext_priv_init, ext_passwd_valid_p, 0, + False, False }, +# endif + { "normal", pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p, 0, + False, False } +}; + + +Bool +lock_priv_init (int argc, char **argv, Bool verbose_p) +{ + int i; + Bool any_ok = False; + for (i = 0; i < countof(methods); i++) + { + if (!methods[i].priv_init) + methods[i].priv_initted_p = True; + else + methods[i].priv_initted_p = methods[i].priv_init (argc, argv, + verbose_p); + + if (methods[i].priv_initted_p) + any_ok = True; + else if (verbose_p) + fprintf (stderr, "%s: initialization of %s passwords failed.\n", + blurb(), methods[i].name); + } + return any_ok; +} + + +Bool +lock_init (int argc, char **argv, Bool verbose_p) +{ + int i; + Bool any_ok = False; + for (i = 0; i < countof(methods); i++) + { + if (!methods[i].priv_initted_p) /* Bail if lock_priv_init failed. */ + continue; + + if (!methods[i].init) + methods[i].initted_p = True; + else + methods[i].initted_p = methods[i].init (argc, argv, verbose_p); + + if (methods[i].initted_p) + any_ok = True; + else if (verbose_p) + fprintf (stderr, "%s: initialization of %s passwords failed.\n", + blurb(), methods[i].name); + } + return any_ok; +} + + +/* A basic auth driver that simply prompts for a password then runs it through + * valid_p to determine whether the password is correct. + */ +static void +try_unlock_password(saver_info *si, + Bool verbose_p, + Bool (*valid_p)(const char *typed_passwd, Bool verbose_p)) +{ + struct auth_message message; + struct auth_response *response = NULL; + + memset(&message, 0, sizeof(message)); + + if (verbose_p) + fprintf(stderr, "%s: non-PAM password auth.\n", blurb()); + + /* Call the auth_conv function with "Password:", then feed + * the result into valid_p() + */ + message.type = AUTH_MSGTYPE_PROMPT_NOECHO; + message.msg = "Password:"; + + si->unlock_cb(1, &message, &response, si); + + if (!response) + return; + + if (valid_p (response->response, verbose_p)) + si->unlock_state = ul_success; /* yay */ + else if (si->unlock_state == ul_cancel || + si->unlock_state == ul_time) + ; /* more specific failures ok */ + else + si->unlock_state = ul_fail; /* generic failure */ + + if (response->response) + free(response->response); + free(response); +} + + +/* Write a password failure to the system log. + */ +static void +do_syslog (saver_info *si, Bool verbose_p) +{ +# ifdef HAVE_SYSLOG + struct passwd *pw = getpwuid (getuid ()); + char *d = DisplayString (si->dpy); + char *u = (pw && pw->pw_name ? pw->pw_name : "???"); + int opt = 0; + int fac = 0; + +# ifdef LOG_PID + opt = LOG_PID; +# endif + +# if defined(LOG_AUTHPRIV) + fac = LOG_AUTHPRIV; +# elif defined(LOG_AUTH) + fac = LOG_AUTH; +# else + fac = LOG_DAEMON; +# endif + + if (!d) d = ""; + +# undef FMT +# define FMT "FAILED LOGIN %d ON DISPLAY \"%s\", FOR \"%s\"" + + if (verbose_p) + fprintf (stderr, "%s: syslog: " FMT "\n", blurb(), + si->unlock_failures, d, u); + + openlog (progname, opt, fac); + syslog (LOG_NOTICE, FMT, si->unlock_failures, d, u); + closelog (); + +# endif /* HAVE_SYSLOG */ +} + + + +/** + * Runs through each authentication driver calling its try_unlock function. + * Called xss_authenticate() because AIX beat us to the name authenticate(). + */ +void +xss_authenticate(saver_info *si, Bool verbose_p) +{ + int i, j; + + si->unlock_state = ul_read; + + for (i = 0; i < countof(methods); i++) + { + if (!methods[i].initted_p) + continue; + + if (si->cached_passwd != NULL && methods[i].valid_p) + si->unlock_state = (methods[i].valid_p(si->cached_passwd, verbose_p) == True) + ? ul_success : ul_fail; + else if (methods[i].try_unlock != NULL) + methods[i].try_unlock(si, verbose_p, methods[i].valid_p); + else if (methods[i].valid_p) + try_unlock_password(si, verbose_p, methods[i].valid_p); + else /* Ze goggles, zey do nozing! */ + fprintf(stderr, "%s: authentication method %s does nothing.\n", + blurb(), methods[i].name); + + check_for_leaks (methods[i].name); + + /* If password authentication failed, but the password was NULL + (meaning the user just hit RET) then treat that as "cancel". + This means that if the password is literally NULL, it will + work; but if not, then NULL passwords are treated as cancel. + */ + if (si->unlock_state == ul_fail && + si->cached_passwd && + !*si->cached_passwd) + { + fprintf (stderr, "%s: assuming null password means cancel.\n", + blurb()); + si->unlock_state = ul_cancel; + } + + if (si->unlock_state == ul_success) + { + /* If we successfully authenticated by method N, but attempting + to authenticate by method N-1 failed, mention that (since if + an earlier authentication method fails and a later one succeeds, + something screwy is probably going on.) + */ + if (verbose_p && i > 0) + { + for (j = 0; j < i; j++) + if (methods[j].initted_p) + fprintf (stderr, + "%s: authentication via %s failed.\n", + blurb(), methods[j].name); + fprintf (stderr, + "%s: authentication via %s succeeded.\n", + blurb(), methods[i].name); + } + goto DONE; /* Successfully authenticated! */ + } + else if (si->unlock_state == ul_cancel || + si->unlock_state == ul_time) + { + /* If any auth method gets a cancel or timeout, don't try the + next auth method! We're done! */ + fprintf (stderr, + "%s: authentication via %s %s.\n", + blurb(), methods[i].name, + (si->unlock_state == ul_cancel + ? "cancelled" : "timed out")); + goto DONE; + } + } + + if (verbose_p) + fprintf(stderr, "%s: All authentication mechanisms failed.\n", blurb()); + + if (si->unlock_state == ul_fail) + { + si->unlock_failures++; + do_syslog (si, verbose_p); + } + +DONE: + if (si->auth_finished_cb) + si->auth_finished_cb (si); +} + +#endif /* NO_LOCKING -- whole file */ diff --git a/driver/pdf2jpeg.m b/driver/pdf2jpeg.m new file mode 100644 index 00000000..d681b4a5 --- /dev/null +++ b/driver/pdf2jpeg.m @@ -0,0 +1,152 @@ +/* pdf2jpeg -- converts a PDF file to a JPEG file, using Cocoa + * + * Copyright (c) 2003, 2008 by 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. + * + * Inspired by clues provided by Jan Kujawa and Jonathan Hendry. + */ + +#import +#include +#include + +int +main (int argc, char** argv) +{ + const char *progname = argv[0]; + const char *infile = 0, *outfile = 0; + double compression = 0.85; + double scale = 1.0; + int verbose = 0; + int i; + + for (i = 1; i < argc; i++) + { + char c; + if (argv[i][0] == '-' && argv[i][1] == '-') + argv[i]++; + if (!strcmp (argv[i], "-q") || + !strcmp (argv[i], "-qual") || + !strcmp (argv[i], "-quality")) + { + int q; + if (1 != sscanf (argv[++i], " %d %c", &q, &c) || + q < 5 || q > 100) + { + fprintf (stderr, "%s: quality must be 5 - 100 (%d)\n", + progname, q); + goto USAGE; + } + compression = q / 100.0; + } + else if (!strcmp (argv[i], "-scale")) + { + float s; + if (1 != sscanf (argv[++i], " %f %c", &s, &c) || + s <= 0 || s > 50) + { + fprintf (stderr, "%s: scale must be 0.0 - 50.0 (%f)\n", + progname, s); + goto USAGE; + } + scale = s; + } + else if (!strcmp (argv[i], "-verbose")) + verbose++; + else if (!strcmp (argv[i], "-v") || + !strcmp (argv[i], "-vv") || + !strcmp (argv[i], "-vvv")) + verbose += strlen(argv[i])-1; + else if (argv[i][0] == '-') + { + fprintf (stderr, "%s: unknown option %s\n", progname, argv[i]); + goto USAGE; + } + else if (!infile) + infile = argv[i]; + else if (!outfile) + outfile = argv[i]; + else + { + USAGE: + fprintf (stderr, + "usage: %s [-verbose] [-scale N] [-quality NN] " + "infile.pdf outfile.jpg\n", + progname); + exit (1); + } + } + + if (!infile || !outfile) + goto USAGE; + + + // Much of Cocoa needs one of these to be available. + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + //Need an NSApp instance to make [NSImage TIFFRepresentation] work + NSApp = [NSApplication sharedApplication]; + [NSApp autorelease]; + + if (verbose) + fprintf (stderr, "%s: reading %s...\n", progname, infile); + + // Load the PDF file into an NSData object: + NSData *pdf_data = [NSData dataWithContentsOfFile: + [NSString stringWithCString:infile + encoding:NSUTF8StringEncoding]]; + + // Create an NSPDFImageRep from the data: + NSPDFImageRep *pdf_rep = [NSPDFImageRep imageRepWithData:pdf_data]; + + // Create an NSImage instance + NSRect rect; + rect.size = [pdf_rep size]; + rect.size.width *= scale; + rect.size.height *= scale; + rect.origin.x = rect.origin.y = 0; + NSImage *image = [[NSImage alloc] initWithSize:rect.size]; + + // Draw the PDFImageRep in the NSImage + [image lockFocus]; + [pdf_rep drawInRect:rect]; + [image unlockFocus]; + + // Load the NSImage's contents into an NSBitmapImageRep: + NSBitmapImageRep *bit_rep = [NSBitmapImageRep + imageRepWithData:[image TIFFRepresentation]]; + + // Write the bitmapImageRep to a JPEG file: + if (bit_rep == nil) + { + fprintf (stderr, "%s: error converting image?\n", argv[0]); + exit (1); + } + + if (verbose) + fprintf (stderr, "%s: writing %s (%d%% quality)...\n", + progname, outfile, (int) (compression * 100)); + + NSDictionary *props = [NSDictionary + dictionaryWithObject: + [NSNumber numberWithFloat:compression] + forKey:NSImageCompressionFactor]; + NSData *jpeg_data = [bit_rep representationUsingType:NSJPEGFileType + properties:props]; + + [jpeg_data writeToFile: + [NSString stringWithCString:outfile + encoding:NSUTF8StringEncoding] + atomically:YES]; + [image release]; + + [pool release]; + exit (0); +} diff --git a/driver/pdf2jpeg.man b/driver/pdf2jpeg.man new file mode 100644 index 00000000..9d80dd76 --- /dev/null +++ b/driver/pdf2jpeg.man @@ -0,0 +1,43 @@ +.TH XScreenSaver 1 "07-Sep-2003 (4.13)" "X Version 11" +.SH NAME +pdf2jpeg - converts a PDF file to a JPEG file using Cocoa +.SH SYNOPSIS +.B pdf2jpeg +[\--verbose] [\--quality \fINN\fP] infile.pdf outfile.jpg +.SH DESCRIPTION +This reads a PDF file (for example, as written by the +.BR screencapture (1) +program) and writes a JPEG file. +.SH OPTIONS +.I pdf2jpeg +accepts the following options: +.TP 4 +.B --verbose +Print diagnostics. +.TP 4 +.B --quality \fINN\fP +JPEG compression factor. Default 85%. +.SH BUGS +The input and output files must be files: pipes don't work. + +This program is Cocoa-specific, so it won't work on non-MacOS systems. + +This shouldn't need to be a part of the XScreenSaver distribution at +all, but Apple is COMPLETELY INSANE and made +.BR screencapture (1) +only write PDFs, with no simple way to convert that to something +less crazy. +.SH SEE ALSO +.BR screencapture (1), +.BR xscreensaver\-getimage\-desktop (1) +.SH COPYRIGHT +Copyright \(co 2003 by 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. +.SH AUTHOR +Jamie Zawinski , 20-Oct-03. diff --git a/driver/prefs.c b/driver/prefs.c new file mode 100644 index 00000000..399a086e --- /dev/null +++ b/driver/prefs.c @@ -0,0 +1,1691 @@ +/* dotfile.c --- management of the ~/.xscreensaver file. + * xscreensaver, Copyright (c) 1998-2013 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include /* for PATH_MAX */ + +#include +#include + +#ifndef VMS +# include +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + + +/* Just in case there's something pathological about stat.h... */ +#ifndef S_IRUSR +# define S_IRUSR 00400 +#endif +#ifndef S_IWUSR +# define S_IWUSR 00200 +#endif +#ifndef S_IXUSR +# define S_IXUSR 00100 +#endif +#ifndef S_IXGRP +# define S_IXGRP 00010 +#endif +#ifndef S_IXOTH +# define S_IXOTH 00001 +#endif + + +#include "version.h" +#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; +extern const char *blurb (void); + + + +static void get_screenhacks (Display *, saver_preferences *); +static char *format_command (const char *cmd, Bool wrap_p); +static void merge_system_screenhacks (Display *, saver_preferences *, + screenhack **system_list, int count); +static void stop_the_insanity (saver_preferences *p); + + +static char * +chase_symlinks (const char *file) +{ +# ifdef HAVE_REALPATH + if (file) + { +# ifndef PATH_MAX +# ifdef MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# else +# define PATH_MAX 2048 +# endif +# endif + char buf[PATH_MAX]; + if (realpath (file, buf)) + return strdup (buf); + +/* sprintf (buf, "%.100s: realpath %.200s", blurb(), file); + perror(buf);*/ + } +# endif /* HAVE_REALPATH */ + return 0; +} + + +static Bool +i_am_a_nobody (uid_t uid) +{ + struct passwd *p; + + p = getpwnam ("nobody"); + if (! p) p = getpwnam ("noaccess"); + if (! p) p = getpwnam ("daemon"); + + if (! p) /* There is no nobody? */ + return False; + + return (uid == p->pw_uid); +} + + +const char * +init_file_name (void) +{ + static char *file = 0; + + if (!file) + { + uid_t uid = getuid (); + struct passwd *p = getpwuid (uid); + + if (i_am_a_nobody (uid)) + /* If we're running as nobody, then use root's .xscreensaver file + (since ~root/.xscreensaver and ~nobody/.xscreensaver are likely + to be different -- if we didn't do this, then xscreensaver-demo + would appear to have no effect when the luser is running as root.) + */ + uid = 0; + + p = getpwuid (uid); + + if (!p || !p->pw_name || !*p->pw_name) + { + fprintf (stderr, "%s: couldn't get user info of uid %d\n", + blurb(), getuid ()); + file = ""; + } + else if (!p->pw_dir || !*p->pw_dir) + { + fprintf (stderr, "%s: couldn't get home directory of \"%s\"\n", + blurb(), (p->pw_name ? p->pw_name : "???")); + file = ""; + } + else + { + const char *home = p->pw_dir; + const char *name = ".xscreensaver"; + file = (char *) malloc(strlen(home) + strlen(name) + 2); + strcpy(file, home); + if (!*home || home[strlen(home)-1] != '/') + strcat(file, "/"); + strcat(file, name); + } + } + + if (file && *file) + return file; + else + return 0; +} + + +static const char * +init_file_tmp_name (void) +{ + static char *file = 0; + if (!file) + { + const char *name = init_file_name(); + const char *suffix = ".tmp"; + + char *n2 = chase_symlinks (name); + if (n2) name = n2; + + if (!name || !*name) + file = ""; + else + { + file = (char *) malloc(strlen(name) + strlen(suffix) + 2); + strcpy(file, name); + strcat(file, suffix); + } + + if (n2) free (n2); + } + + if (file && *file) + return file; + else + return 0; +} + +static int +get_byte_resource (Display *dpy, char *name, char *class) +{ + char *s = get_string_resource (dpy, name, class); + char *s2 = s; + int n = 0; + if (!s) return 0; + + while (isspace(*s2)) s2++; + while (*s2 >= '0' && *s2 <= '9') + { + n = (n * 10) + (*s2 - '0'); + s2++; + } + while (isspace(*s2)) s2++; + if (*s2 == 'k' || *s2 == 'K') n <<= 10; + else if (*s2 == 'm' || *s2 == 'M') n <<= 20; + else if (*s2 == 'g' || *s2 == 'G') n <<= 30; + else if (*s2) + { + LOSE: + fprintf (stderr, "%s: %s must be a number of bytes, not \"%s\".\n", + progname, name, s); + free (s); + return 0; + } + s2++; + if (*s2 == 'b' || *s2 == 'B') s2++; + while (isspace(*s2)) s2++; + if (*s2) goto LOSE; + + free (s); + return n; +} + + +static const char * const prefs[] = { + "timeout", + "cycle", + "lock", + "lockVTs", /* not saved */ + "lockTimeout", + "passwdTimeout", + "visualID", + "installColormap", + "verbose", + "timestamp", + "splash", + "splashDuration", + "quad", + "demoCommand", + "prefsCommand", + "newLoginCommand", + "helpURL", /* not saved */ + "loadURL", /* not saved */ + "newLoginCommand", /* not saved */ + "nice", + "memoryLimit", + "fade", + "unfade", + "fadeSeconds", + "fadeTicks", + "captureStderr", + "captureStdout", /* not saved -- obsolete */ + "logFile", /* not saved */ + "ignoreUninstalledPrograms", + "font", + "dpmsEnabled", + "dpmsQuickOff", + "dpmsStandby", + "dpmsSuspend", + "dpmsOff", + "grabDesktopImages", + "grabVideoFrames", + "chooseRandomImages", + "imageDirectory", + "mode", + "selected", + "textMode", + "textLiteral", + "textFile", + "textProgram", + "textURL", + "", + "programs", + "", + "pointerPollTime", + "pointerHysteresis", + "windowCreationTimeout", + "initialDelay", + "sgiSaverExtension", /* not saved -- obsolete */ + "mitSaverExtension", /* not saved -- obsolete */ + "xidleExtension", /* not saved -- obsolete */ + "GetViewPortIsFullOfLies", + "procInterrupts", + "xinputExtensionDev", + "overlayStderr", + "overlayTextBackground", /* not saved -- X resources only */ + "overlayTextForeground", /* not saved -- X resources only */ + "bourneShell", /* not saved -- X resources only */ + 0 +}; + +static char * +strip (char *s) +{ + char *s2; + while (*s == '\t' || *s == ' ' || *s == '\r' || *s == '\n') + s++; + for (s2 = s; *s2; s2++) + ; + for (s2--; s2 >= s; s2--) + if (*s2 == '\t' || *s2 == ' ' || *s2 == '\r' || *s2 =='\n') + *s2 = 0; + else + break; + return s; +} + + +/* Reading + */ + +static int +handle_entry (XrmDatabase *db, const char *key, const char *value, + const char *filename, int line) +{ + int i; + for (i = 0; prefs[i]; i++) + if (*prefs[i] && !strcasecmp(key, prefs[i])) + { + char *val = strdup(value); + char *spec = (char *) malloc(strlen(progclass) + strlen(prefs[i]) +10); + strcpy(spec, progclass); + strcat(spec, "."); + strcat(spec, prefs[i]); + + XrmPutStringResource (db, spec, val); + + free(spec); + free(val); + return 0; + } + + fprintf(stderr, "%s: %s:%d: unknown option \"%s\"\n", + blurb(), filename, line, key); + return 1; +} + + +static int +parse_init_file (saver_preferences *p) +{ + time_t write_date = 0; + const char *name = init_file_name(); + int line = 0; + struct stat st; + FILE *in; + int buf_size = 1024; + char *buf; + + if (!name) return 0; + + if (stat(name, &st) != 0) + { + p->init_file_date = 0; + return 0; + } + + in = fopen(name, "r"); + if (!in) + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: error reading \"%s\"", blurb(), name); + perror(buf); + free(buf); + return -1; + } + + if (fstat (fileno(in), &st) == 0) + { + write_date = st.st_mtime; + } + else + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: couldn't re-stat \"%s\"", blurb(), name); + perror(buf); + free(buf); + return -1; + } + + buf = (char *) malloc(buf_size); + + while (fgets (buf, buf_size-1, in)) + { + char *key, *value; + int L = strlen(buf); + + line++; + while (L > 2 && + (buf[L-1] != '\n' || /* whole line didn't fit in buffer */ + buf[L-2] == '\\')) /* or line ended with backslash */ + { + if (buf[L-2] == '\\') /* backslash-newline gets swallowed */ + { + buf[L-2] = 0; + L -= 2; + } + buf_size += 1024; + buf = (char *) realloc(buf, buf_size); + if (!buf) exit(1); + + line++; + if (!fgets (buf + L, buf_size-L-1, in)) + break; + L = strlen(buf); + } + + /* Now handle other backslash escapes. */ + { + int i, j; + for (i = 0; buf[i]; i++) + if (buf[i] == '\\') + { + switch (buf[i+1]) + { + case 'n': buf[i] = '\n'; break; + case 'r': buf[i] = '\r'; break; + case 't': buf[i] = '\t'; break; + default: buf[i] = buf[i+1]; break; + } + for (j = i+2; buf[j]; j++) + buf[j-1] = buf[j]; + buf[j-1] = 0; + } + } + + key = strip(buf); + + if (*key == '#' || *key == '!' || *key == ';' || + *key == '\n' || *key == 0) + continue; + + value = strchr (key, ':'); + if (!value) + { + fprintf(stderr, "%s: %s:%d: unparsable line: %s\n", blurb(), + name, line, key); + continue; + } + else + { + *value++ = 0; + value = strip(value); + } + + if (!p->db) abort(); + handle_entry (&p->db, key, value, name, line); + } + fclose (in); + free(buf); + + p->init_file_date = write_date; + return 0; +} + + +Bool +init_file_changed_p (saver_preferences *p) +{ + const char *name = init_file_name(); + struct stat st; + + if (!name) return False; + + if (stat(name, &st) != 0) + return False; + + if (p->init_file_date == st.st_mtime) + return False; + + return True; +} + + +/* Writing + */ + +static int +tab_to (FILE *out, int from, int to) +{ + int tab_width = 8; + int to_mod = (to / tab_width) * tab_width; + while (from < to_mod) + { + fprintf(out, "\t"); + from = (((from / tab_width) + 1) * tab_width); + } + while (from < to) + { + fprintf(out, " "); + from++; + } + return from; +} + +static char * +stab_to (char *out, int from, int to) +{ + int tab_width = 8; + int to_mod = (to / tab_width) * tab_width; + while (from < to_mod) + { + *out++ = '\t'; + from = (((from / tab_width) + 1) * tab_width); + } + while (from < to) + { + *out++ = ' '; + from++; + } + return out; +} + +static int +string_columns (const char *string, int length, int start) +{ + int tab_width = 8; + int col = start; + const char *end = string + length; + while (string < end) + { + if (*string == '\n') + col = 0; + else if (*string == '\t') + col = (((col / tab_width) + 1) * tab_width); + else + col++; + string++; + } + return col; +} + + +static void +write_entry (FILE *out, const char *key, const char *value) +{ + char *v = strdup(value ? value : ""); + char *v2 = v; + char *nl = 0; + int col; + Bool programs_p = (!strcmp(key, "programs")); + int tab = (programs_p ? 32 : 16); + Bool first = True; + + fprintf(out, "%s:", key); + col = strlen(key) + 1; + + if (strlen(key) > 14) + col = tab_to (out, col, 20); + + while (1) + { + if (!programs_p) + v2 = strip(v2); + nl = strchr(v2, '\n'); + if (nl) + *nl = 0; + + if (first && programs_p) + { + col = tab_to (out, col, 77); + fprintf (out, " \\\n"); + col = 0; + } + + if (first) + first = False; + else + { + col = tab_to (out, col, 75); + fprintf (out, " \\n\\\n"); + col = 0; + } + + if (!programs_p) + col = tab_to (out, col, tab); + + if (programs_p && + string_columns(v2, strlen (v2), col) + col > 75) + { + int L = strlen (v2); + int start = 0; + int end = start; + while (start < L) + { + while (v2[end] == ' ' || v2[end] == '\t') + end++; + while (v2[end] != ' ' && v2[end] != '\t' && + v2[end] != '\n' && v2[end] != 0) + end++; + if (string_columns (v2 + start, (end - start), col) >= 74) + { + col = tab_to (out, col, 75); + fprintf(out, " \\\n"); + col = tab_to (out, 0, tab + 2); + while (v2[start] == ' ' || v2[start] == '\t') + start++; + } + + col = string_columns (v2 + start, (end - start), col); + while (start < end) + fputc(v2[start++], out); + } + } + else + { + fprintf (out, "%s", v2); + col += string_columns(v2, strlen (v2), col); + } + + if (nl) + v2 = nl + 1; + else + break; + } + + fprintf(out, "\n"); + free(v); +} + +int +write_init_file (Display *dpy, + saver_preferences *p, const char *version_string, + Bool verbose_p) +{ + int status = -1; + const char *name = init_file_name(); + const char *tmp_name = init_file_tmp_name(); + char *n2 = chase_symlinks (name); + struct stat st; + int i, j; + + /* Kludge, since these aren't in the saver_preferences struct as strings... + */ + char *visual_name; + char *programs; + Bool overlay_stderr_p; + char *stderr_font; + FILE *out; + + if (!name) goto END; + + if (n2) name = n2; + + /* Throttle the various timeouts to reasonable values before writing + the file to disk. */ + stop_the_insanity (p); + + + if (verbose_p) + fprintf (stderr, "%s: writing \"%s\".\n", blurb(), name); + + unlink (tmp_name); + out = fopen(tmp_name, "w"); + if (!out) + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: error writing \"%s\"", blurb(), name); + perror(buf); + free(buf); + goto END; + } + + /* Give the new .xscreensaver file the same permissions as the old one; + except ensure that it is readable and writable by owner, and not + executable. Extra hack: if we're running as root, make the file + be world-readable (so that the daemon, running as "nobody", will + still be able to read it.) + */ + if (stat(name, &st) == 0) + { + mode_t mode = st.st_mode; + mode |= S_IRUSR | S_IWUSR; /* read/write by user */ + mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); /* executable by none */ + + if (getuid() == (uid_t) 0) /* read by group/other */ + mode |= S_IRGRP | S_IROTH; + + if (fchmod (fileno(out), mode) != 0) + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf (buf, "%s: error fchmodding \"%s\" to 0%o", blurb(), + tmp_name, (unsigned int) mode); + perror(buf); + free(buf); + goto END; + } + } + + /* Kludge, since these aren't in the saver_preferences struct... */ + visual_name = get_string_resource (dpy, "visualID", "VisualID"); + programs = 0; + overlay_stderr_p = get_boolean_resource (dpy, "overlayStderr", "Boolean"); + stderr_font = get_string_resource (dpy, "font", "Font"); + + i = 0; + { + char *ss; + char **hack_strings = (char **) + calloc (p->screenhacks_count, sizeof(char *)); + + for (j = 0; j < p->screenhacks_count; j++) + { + hack_strings[j] = format_hack (dpy, p->screenhacks[j], True); + i += strlen (hack_strings[j]); + i += 2; + } + + ss = programs = (char *) malloc(i + 10); + *ss = 0; + for (j = 0; j < p->screenhacks_count; j++) + { + strcat (ss, hack_strings[j]); + free (hack_strings[j]); + ss += strlen(ss); + *ss++ = '\n'; + *ss = 0; + } + free (hack_strings); + } + + { + struct passwd *pw = getpwuid (getuid ()); + char *whoami = (pw && pw->pw_name && *pw->pw_name + ? pw->pw_name + : ""); + time_t now = time ((time_t *) 0); + char *timestr = (char *) ctime (&now); + char *nl = (char *) strchr (timestr, '\n'); + if (nl) *nl = 0; + fprintf (out, + "# %s Preferences File\n" + "# Written by %s %s for %s on %s.\n" + "# http://www.jwz.org/xscreensaver/\n" + "\n", + progclass, progname, version_string, whoami, timestr); + } + + for (j = 0; prefs[j]; j++) + { + char buf[255]; + const char *pr = prefs[j]; + enum pref_type { pref_str, pref_int, pref_bool, pref_byte, pref_time + } type = pref_str; + const char *s = 0; + int i = 0; + Bool b = False; + Time t = 0; + + if (pr && !*pr) + { + fprintf(out, "\n"); + continue; + } + +# undef CHECK +# define CHECK(X) else if (!strcmp(pr, X)) + if (!pr || !*pr) ; + 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; + 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; + CHECK("installColormap") type = pref_bool, b = p->install_cmap_p; + CHECK("verbose") type = pref_bool, b = p->verbose_p; + 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; */ + CHECK("helpURL") continue; /* don't save */ +/* CHECK("loadURL") type = pref_str, s = p->load_url_command; */ + CHECK("loadURL") continue; /* don't save */ +/* CHECK("newLoginCommand") type = pref_str, s = p->new_login_command; */ + CHECK("newLoginCommand") continue; /* don't save */ + CHECK("nice") type = pref_int, i = p->nice_inferior; + CHECK("memoryLimit") type = pref_byte, i = p->inferior_memory_limit; + CHECK("fade") type = pref_bool, b = p->fade_p; + CHECK("unfade") type = pref_bool, b = p->unfade_p; + CHECK("fadeSeconds") type = pref_time, t = p->fade_seconds; + CHECK("fadeTicks") type = pref_int, i = p->fade_ticks; + CHECK("captureStderr") type = pref_bool, b = p->capture_stderr_p; + CHECK("captureStdout") continue; /* don't save */ + CHECK("logFile") continue; /* don't save */ + CHECK("ignoreUninstalledPrograms") + type = pref_bool, b = p->ignore_uninstalled_p; + + CHECK("font") type = pref_str, s = stderr_font; + + CHECK("dpmsEnabled") type = pref_bool, b = p->dpms_enabled_p; + CHECK("dpmsQuickOff") type = pref_bool, b = p->dpms_quickoff_p; + CHECK("dpmsStandby") type = pref_time, t = p->dpms_standby; + CHECK("dpmsSuspend") type = pref_time, t = p->dpms_suspend; + CHECK("dpmsOff") type = pref_time, t = p->dpms_off; + + CHECK("grabDesktopImages") type =pref_bool, b = p->grab_desktop_p; + CHECK("grabVideoFrames") type =pref_bool, b = p->grab_video_p; + CHECK("chooseRandomImages")type =pref_bool, b = p->random_image_p; + CHECK("imageDirectory") type =pref_str, s = p->image_directory; + + CHECK("mode") type = pref_str, + s = (p->mode == ONE_HACK ? "one" : + p->mode == BLANK_ONLY ? "blank" : + p->mode == DONT_BLANK ? "off" : + p->mode == RANDOM_HACKS_SAME + ? "random-same" + : "random"); + CHECK("selected") type = pref_int, i = p->selected_hack; + + CHECK("textMode") type = pref_str, + s = (p->tmode == TEXT_URL ? "url" : + p->tmode == TEXT_LITERAL ? "literal" : + p->tmode == TEXT_FILE ? "file" : + p->tmode == TEXT_PROGRAM ? "program" : + "date"); + CHECK("textLiteral") type = pref_str, s = p->text_literal; + CHECK("textFile") type = pref_str, s = p->text_file; + CHECK("textProgram") type = pref_str, s = p->text_program; + CHECK("textURL") type = pref_str, s = p->text_url; + + CHECK("programs") type = pref_str, s = programs; + CHECK("pointerPollTime") type = pref_time, t = p->pointer_timeout; + CHECK("pointerHysteresis")type = pref_int, i = p->pointer_hysteresis; + CHECK("windowCreationTimeout")type=pref_time,t= p->notice_events_timeout; + CHECK("initialDelay") type = pref_time, t = p->initial_delay; + CHECK("sgiSaverExtension") continue; /* don't save */ + CHECK("mitSaverExtension") continue; /* don't save */ + CHECK("xidleExtension") continue; /* don't save */ + CHECK("procInterrupts") type = pref_bool, b = p->use_proc_interrupts; + CHECK("xinputExtensionDev") type = pref_bool, b = p->use_xinput_extension; + CHECK("GetViewPortIsFullOfLies") type = pref_bool, + b = p->getviewport_full_of_lies_p; + CHECK("overlayStderr") type = pref_bool, b = overlay_stderr_p; + CHECK("overlayTextBackground") continue; /* don't save */ + CHECK("overlayTextForeground") continue; /* don't save */ + CHECK("bourneShell") continue; /* don't save */ + else abort(); +# undef CHECK + + switch (type) + { + case pref_str: + break; + case pref_int: + sprintf(buf, "%d", i); + s = buf; + break; + case pref_bool: + s = b ? "True" : "False"; + break; + case pref_time: + { + unsigned int hour = 0, min = 0, sec = (unsigned int) (t/1000); + if (sec >= 60) + { + min += (sec / 60); + sec %= 60; + } + if (min >= 60) + { + hour += (min / 60); + min %= 60; + } + sprintf (buf, "%u:%02u:%02u", hour, min, sec); + s = buf; + } + break; + case pref_byte: + { + if (i >= (1<<30) && i == ((i >> 30) << 30)) + sprintf(buf, "%dG", i >> 30); + else if (i >= (1<<20) && i == ((i >> 20) << 20)) + sprintf(buf, "%dM", i >> 20); + else if (i >= (1<<10) && i == ((i >> 10) << 10)) + sprintf(buf, "%dK", i >> 10); + else + sprintf(buf, "%d", i); + s = buf; + } + break; + default: + abort(); + break; + } + + if (pr && (!strcmp(pr, "mode") || !strcmp(pr, "textMode"))) + fprintf(out, "\n"); + + write_entry (out, pr, s); + } + + fprintf(out, "\n"); + + if (visual_name) free(visual_name); + if (stderr_font) free(stderr_font); + if (programs) free(programs); + + if (fclose(out) == 0) + { + time_t write_date = 0; + + if (stat(tmp_name, &st) == 0) + { + write_date = st.st_mtime; + } + else + { + char *buf = (char *) malloc(1024 + strlen(tmp_name) + strlen(name)); + sprintf(buf, "%s: couldn't stat \"%s\"", blurb(), tmp_name); + perror(buf); + unlink (tmp_name); + free(buf); + goto END; + } + + if (rename (tmp_name, name) != 0) + { + char *buf = (char *) malloc(1024 + strlen(tmp_name) + strlen(name)); + sprintf(buf, "%s: error renaming \"%s\" to \"%s\"", + blurb(), tmp_name, name); + perror(buf); + unlink (tmp_name); + free(buf); + goto END; + } + else + { + p->init_file_date = write_date; + + /* Since the .xscreensaver file is used for IPC, let's try and make + sure that the bits actually land on the disk right away. */ + sync (); + + status = 0; /* wrote and renamed successfully! */ + } + } + else + { + char *buf = (char *) malloc(1024 + strlen(name)); + sprintf(buf, "%s: error closing \"%s\"", blurb(), name); + perror(buf); + free(buf); + unlink (tmp_name); + goto END; + } + + END: + if (n2) free (n2); + return status; +} + + +/* Parsing the resource database + */ + +void +free_screenhack (screenhack *hack) +{ + if (hack->visual) free (hack->visual); + if (hack->name) free (hack->name); + free (hack->command); + memset (hack, 0, sizeof(*hack)); + free (hack); +} + +static void +free_screenhack_list (screenhack **list, int count) +{ + int i; + if (!list) return; + for (i = 0; i < count; i++) + if (list[i]) + free_screenhack (list[i]); + free (list); +} + + + +/* Populate `saver_preferences' with the contents of the resource database. + Note that this may be called multiple times -- it is re-run each time + the ~/.xscreensaver file is reloaded. + + This function can be very noisy, since it issues resource syntax errors + and so on. + */ +void +load_init_file (Display *dpy, saver_preferences *p) +{ + static Bool first_time = True; + + screenhack **system_default_screenhacks = 0; + int system_default_screenhack_count = 0; + + if (first_time) + { + /* Get the programs resource before the .xscreensaver file has been + parsed and merged into the resource database for the first time: + this is the value of *programs from the app-defaults file. + Then clear it out so that it will be parsed again later, after + the init file has been read. + */ + get_screenhacks (dpy, p); + system_default_screenhacks = p->screenhacks; + system_default_screenhack_count = p->screenhacks_count; + p->screenhacks = 0; + p->screenhacks_count = 0; + } + + if (parse_init_file (p) != 0) /* file might have gone away */ + if (!first_time) return; + + first_time = False; + + 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 (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 (dpy, "dpmsEnabled", "Boolean"); + p->dpms_quickoff_p = get_boolean_resource (dpy, "dpmsQuickOff", "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 (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 (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 (dpy, "bourneShell", "BourneShell"); + + 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 (dpy, "splash", "Boolean"); + if (s) + free (s); + else + p->splash_p = True; + } + + /* If "*grabDesktopImages" is unset, default to true. */ + { + 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 (dpy, "xidleExtension","Boolean"); +#if 0 /* obsolete. */ + p->use_sgi_saver_extension = get_boolean_resource (dpy, + "sgiSaverExtension", + "Boolean"); +#endif +#ifdef HAVE_XINPUT + p->use_xinput_extension = get_boolean_resource (dpy, "xinputExtensionDev", + "Boolean"); +#endif +#if 0 /* broken and evil. */ + p->use_mit_saver_extension = get_boolean_resource (dpy, + "mitSaverExtension", + "Boolean"); +#endif + + p->use_proc_interrupts = get_boolean_resource (dpy, + "procInterrupts", "Boolean"); + + p->getviewport_full_of_lies_p = + get_boolean_resource (dpy, "GetViewPortIsFullOfLies", "Boolean"); + + get_screenhacks (dpy, p); /* Parse the "programs" resource. */ + + { + char *s = get_string_resource (dpy, "selected", "Integer"); + if (!s || !*s) + p->selected_hack = -1; + else + 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 (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; + else if (s && !strcasecmp (s, "random-same")) p->mode = RANDOM_HACKS_SAME; + else p->mode = RANDOM_HACKS; + if (s) free (s); + } + + { + 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; + else if (s && !strcasecmp (s, "program")) p->tmode = TEXT_PROGRAM; + else p->tmode = TEXT_DATE; + if (s) free (s); + } + + if (system_default_screenhack_count) /* note: first_time is also true */ + { + merge_system_screenhacks (dpy, p, system_default_screenhacks, + system_default_screenhack_count); + free_screenhack_list (system_default_screenhacks, + system_default_screenhack_count); + system_default_screenhacks = 0; + system_default_screenhack_count = 0; + } + + if (p->debug_p) + { + p->xsync_p = True; + p->verbose_p = True; + p->timestamp_p = True; + p->initial_delay = 0; + } + + /* Throttle the various timeouts to reasonable values after reading the + disk file. */ + stop_the_insanity (p); +} + + +/* If there are any hacks in the system-wide defaults that are not in + the ~/.xscreensaver file, add the new ones to the end of the list. + This does *not* actually save the file. + */ +static void +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, + so fuck it. */ + + int made_space = 0; + int i; + for (i = 0; i < system_count; i++) + { + int j; + Bool matched_p = False; + + for (j = 0; j < p->screenhacks_count; j++) + { + char *name; + if (!system_list[i]->name) + system_list[i]->name = make_hack_name (dpy, + system_list[i]->command); + + name = p->screenhacks[j]->name; + if (!name) + name = make_hack_name (dpy, p->screenhacks[j]->command); + + matched_p = !strcasecmp (name, system_list[i]->name); + + if (name != p->screenhacks[j]->name) + free (name); + + if (matched_p) + break; + } + + if (!matched_p) + { + /* We have an entry in the system-wide list that is not in the + user's .xscreensaver file. Add it to the end. + Note that p->screenhacks is a single malloc block, not a + linked list, so we have to realloc it. + */ + screenhack *oh = system_list[i]; + screenhack *nh = (screenhack *) malloc (sizeof(screenhack)); + + if (made_space == 0) + { + made_space = 10; + p->screenhacks = (screenhack **) + realloc (p->screenhacks, + (p->screenhacks_count + made_space + 1) + * sizeof(screenhack)); + if (!p->screenhacks) abort(); + } + + nh->enabled_p = oh->enabled_p; + nh->visual = oh->visual ? strdup(oh->visual) : 0; + nh->name = oh->name ? strdup(oh->name) : 0; + nh->command = oh->command ? strdup(oh->command) : 0; + + p->screenhacks[p->screenhacks_count++] = nh; + p->screenhacks[p->screenhacks_count] = 0; + made_space--; + +#if 0 + fprintf (stderr, "%s: noticed new hack: %s\n", blurb(), + (nh->name ? nh->name : make_hack_name (dpy, nh->command))); +#endif + } + } +} + + + +/* Parsing the programs resource. + */ + +screenhack * +parse_screenhack (const char *line) +{ + screenhack *h = (screenhack *) calloc (1, sizeof(*h)); + const char *s; + + h->enabled_p = True; + + while (isspace(*line)) line++; /* skip whitespace */ + if (*line == '-') /* handle "-" */ + { + h->enabled_p = False; + line++; + while (isspace(*line)) line++; /* skip whitespace */ + } + + s = line; /* handle "visual:" */ + while (*line && *line != ':' && *line != '"' && !isspace(*line)) + line++; + if (*line != ':') + line = s; + else + { + h->visual = (char *) malloc (line-s+1); + strncpy (h->visual, s, line-s); + h->visual[line-s] = 0; + if (*line == ':') line++; /* skip ":" */ + while (isspace(*line)) line++; /* skip whitespace */ + } + + if (*line == '"') /* handle "name" */ + { + line++; + s = line; + while (*line && *line != '"') + line++; + h->name = (char *) malloc (line-s+1); + strncpy (h->name, s, line-s); + h->name[line-s] = 0; + if (*line == '"') line++; /* skip "\"" */ + while (isspace(*line)) line++; /* skip whitespace */ + } + + h->command = format_command (line, False); /* handle command */ + return h; +} + + +static char * +format_command (const char *cmd, Bool wrap_p) +{ + int tab = 30; + int col = tab; + char *cmd2 = (char *) calloc (1, 2 * (strlen (cmd) + 1)); + const char *in = cmd; + char *out = cmd2; + while (*in) + { + /* shrink all whitespace to one space, for the benefit of the "demo" + mode display. We only do this when we can easily tell that the + whitespace is not significant (no shell metachars). + */ + switch (*in) + { + case '\'': case '"': case '`': case '\\': + /* Metachars are scary. Copy the rest of the line unchanged. */ + while (*in) + *out++ = *in++, col++; + break; + + case ' ': case '\t': + /* Squeeze all other whitespace down to one space. */ + while (*in == ' ' || *in == '\t') + in++; + *out++ = ' ', col++; + break; + + default: + /* Copy other chars unchanged. */ + *out++ = *in++, col++; + break; + } + } + + *out = 0; + + /* Strip trailing whitespace */ + while (out > cmd2 && isspace (out[-1])) + *(--out) = 0; + + return cmd2; +} + + +/* Returns a new string describing the shell command. + This may be just the name of the program, capitalized. + It also may be something from the resource database (gotten + by looking for "hacks.XYZ.name", where XYZ is the program.) + */ +char * +make_hack_name (Display *dpy, const char *shell_command) +{ + char *s = strdup (shell_command); + char *s2; + char res_name[255]; + + for (s2 = s; *s2; s2++) /* truncate at first whitespace */ + if (isspace (*s2)) + { + *s2 = 0; + break; + } + + s2 = strrchr (s, '/'); /* if pathname, take last component */ + if (s2) + { + s2 = strdup (s2+1); + free (s); + s = s2; + } + + if (strlen (s) > 50) /* 51 is hereby defined as "unreasonable" */ + s[50] = 0; + + sprintf (res_name, "hacks.%s.name", s); /* resource? */ + s2 = get_string_resource (dpy, res_name, res_name); + if (s2) + { + free (s); + return s2; + } + + for (s2 = s; *s2; s2++) /* if it has any capitals, return it */ + if (*s2 >= 'A' && *s2 <= 'Z') + return s; + + if (s[0] >= 'a' && s[0] <= 'z') /* else cap it */ + s[0] -= 'a'-'A'; + if (s[0] == 'X' && s[1] >= 'a' && s[1] <= 'z') /* (magic leading X) */ + s[1] -= 'a'-'A'; + if (s[0] == 'G' && s[1] == 'l' && + s[2] >= 'a' && s[2] <= 'z') /* (magic leading GL) */ + s[1] -= 'a'-'A', + s[2] -= 'a'-'A'; + return s; +} + + +char * +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 (dpy, hack->command); + + /* Don't ever write out a name for a hack if it's the same as the default. + */ + if (hack->name && !strcmp (hack->name, def_name)) + { + free (hack->name); + hack->name = 0; + } + free (def_name); + + size = (2 * (strlen(hack->command) + + (hack->visual ? strlen(hack->visual) : 0) + + (hack->name ? strlen(hack->name) : 0) + + tab)); + h2 = (char *) malloc (size); + out = h2; + + if (!hack->enabled_p) *out++ = '-'; /* write disabled flag */ + + if (hack->visual && *hack->visual) /* write visual name */ + { + if (hack->enabled_p) *out++ = ' '; + *out++ = ' '; + strcpy (out, hack->visual); + out += strlen (hack->visual); + *out++ = ':'; + *out++ = ' '; + } + + *out = 0; + col = string_columns (h2, strlen (h2), 0); + + if (hack->name && *hack->name) /* write pretty name */ + { + int L = (strlen (hack->name) + 2); + if (L + col < tab) + out = stab_to (out, col, tab - L - 2); + else + *out++ = ' '; + *out++ = '"'; + strcpy (out, hack->name); + out += strlen (hack->name); + *out++ = '"'; + *out = 0; + + col = string_columns (h2, strlen (h2), 0); + if (wrap_p && col >= tab) + out = stab_to (out, col, 77); + else + *out++ = ' '; + + if (out >= h2+size) abort(); + } + + *out = 0; + col = string_columns (h2, strlen (h2), 0); + out = stab_to (out, col, tab); /* indent */ + + if (out >= h2+size) abort(); + s = format_command (hack->command, wrap_p); + strcpy (out, s); + out += strlen (s); + free (s); + *out = 0; + + return h2; +} + + +static void +get_screenhacks (Display *dpy, saver_preferences *p) +{ + int i, j; + int start = 0; + int end = 0; + int size; + char *d; + + d = get_string_resource (dpy, "monoPrograms", "MonoPrograms"); + if (d && !*d) { free(d); d = 0; } + if (!d) + d = get_string_resource (dpy, "colorPrograms", "ColorPrograms"); + if (d && !*d) { free(d); d = 0; } + + if (d) + { + fprintf (stderr, + "%s: the `monoPrograms' and `colorPrograms' resources are obsolete;\n\ + see the manual for details.\n", blurb()); + free(d); + } + + d = get_string_resource (dpy, "programs", "Programs"); + + free_screenhack_list (p->screenhacks, p->screenhacks_count); + p->screenhacks = 0; + p->screenhacks_count = 0; + + if (!d || !*d) + return; + + size = strlen (d); + + + /* Count up the number of newlines (which will be equal to or larger than + one less than the number of hacks.) + */ + for (i = j = 0; d[i]; i++) + if (d[i] == '\n') + j++; + j++; + + p->screenhacks = (screenhack **) calloc (j + 1, sizeof (screenhack *)); + + /* Iterate over the lines in `d' (the string with newlines) + and make new strings to stuff into the `screenhacks' array. + */ + p->screenhacks_count = 0; + while (start < size) + { + /* skip forward over whitespace. */ + while (d[start] == ' ' || d[start] == '\t' || d[start] == '\n') + start++; + + /* skip forward to newline or end of string. */ + end = start; + while (d[end] != 0 && d[end] != '\n') + end++; + + /* null terminate. */ + d[end] = 0; + + p->screenhacks[p->screenhacks_count++] = parse_screenhack (d + start); + if (p->screenhacks_count >= i) + abort(); + + start = end+1; + } + + free (d); + + if (p->screenhacks_count == 0) + { + free (p->screenhacks); + p->screenhacks = 0; + } +} + + +/* Make sure all the values in the preferences struct are sane. + */ +static void +stop_the_insanity (saver_preferences *p) +{ + if (p->passwd_timeout <= 0) p->passwd_timeout = 30000; /* 30 secs */ + if (p->timeout < 15000) p->timeout = 15000; /* 15 secs */ + if (p->cycle != 0 && p->cycle < 2000) p->cycle = 2000; /* 2 secs */ + if (p->pointer_timeout <= 0) p->pointer_timeout = 5000; /* 5 secs */ + if (p->notice_events_timeout <= 0) + p->notice_events_timeout = 10000; /* 10 secs */ + if (p->fade_seconds <= 0 || p->fade_ticks <= 0) + p->fade_p = False; + if (! p->fade_p) p->unfade_p = False; + + /* The DPMS settings may have the value 0. + But if they are negative, or are a range less than 10 seconds, + reset them to sensible defaults. (Since that must be a mistake.) + */ + if (p->dpms_standby != 0 && + p->dpms_standby < 10 * 1000) + p->dpms_standby = 2 * 60 * 60 * 1000; /* 2 hours */ + if (p->dpms_suspend != 0 && + p->dpms_suspend < 10 * 1000) + p->dpms_suspend = 2 * 60 * 60 * 1000; /* 2 hours */ + if (p->dpms_off != 0 && + p->dpms_off < 10 * 1000) + p->dpms_off = 4 * 60 * 60 * 1000; /* 4 hours */ + + /* suspend may not be greater than off, unless off is 0. + standby may not be greater than suspend, unless suspend is 0. + */ + if (p->dpms_off != 0 && + p->dpms_suspend > p->dpms_off) + p->dpms_suspend = p->dpms_off; + if (p->dpms_suspend != 0 && + 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 && + p->dpms_off == 0) + p->dpms_enabled_p = False; + + + /* Set watchdog timeout to about half of the cycle timeout, but + don't let it be faster than 1/2 minute or slower than 1 minute. + */ + p->watchdog_timeout = p->cycle * 0.6; + if (p->watchdog_timeout < 27000) p->watchdog_timeout = 27000; /* 27 secs */ + if (p->watchdog_timeout > 57000) p->watchdog_timeout = 57000; /* 57 secs */ + + if (p->pointer_hysteresis < 0) p->pointer_hysteresis = 0; + if (p->pointer_hysteresis > 100) p->pointer_hysteresis = 100; +} + + +/* Getting very tired of bug reports of already-fixed bugs due to + Linux distros shipping multi-year-old versions. + */ +Bool +senescent_p (void) +{ + time_t now = time ((time_t *) 0); + struct tm *tm = localtime (&now); + const char *s = screensaver_id; + char mon[4], year[5]; + int m, y, months; + s = strchr (s, ' '); if (!s) abort(); s++; + s = strchr (s, '('); if (!s) abort(); s++; + s = strchr (s, '-'); if (!s) abort(); s++; + strncpy (mon, s, 3); + mon[3] = 0; + s = strchr (s, '-'); if (!s) abort(); s++; + strncpy (year, s, 4); + year[4] = 0; + y = atoi (year); + if (!strcmp(mon, "Jan")) m = 0; + else if (!strcmp(mon, "Feb")) m = 1; + else if (!strcmp(mon, "Mar")) m = 2; + else if (!strcmp(mon, "Apr")) m = 3; + else if (!strcmp(mon, "May")) m = 4; + else if (!strcmp(mon, "Jun")) m = 5; + else if (!strcmp(mon, "Jul")) m = 6; + else if (!strcmp(mon, "Aug")) m = 7; + else if (!strcmp(mon, "Sep")) m = 8; + else if (!strcmp(mon, "Oct")) m = 9; + else if (!strcmp(mon, "Nov")) m = 10; + else if (!strcmp(mon, "Dec")) m = 11; + else abort(); + months = ((((tm->tm_year + 1900) * 12) + tm->tm_mon) - + (y * 12 + m)); + + return (months > 12); +} diff --git a/driver/prefs.h b/driver/prefs.h new file mode 100644 index 00000000..ecbb4907 --- /dev/null +++ b/driver/prefs.h @@ -0,0 +1,36 @@ +/* xscreensaver, Copyright (c) 1993-2013 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_PREFS_H__ +#define __XSCREENSAVER_PREFS_H__ + +#include "types.h" + +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 Bool senescent_p (void); + +extern screenhack *parse_screenhack (const char *line); +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 *, Bool enabled_p, + int standby_secs, int suspend_secs, + int off_secs, + Bool verbose_p); + +#endif /* __XSCREENSAVER_PREFS_H__ */ diff --git a/driver/remote.c b/driver/remote.c new file mode 100644 index 00000000..775036ac --- /dev/null +++ b/driver/remote.c @@ -0,0 +1,595 @@ +/* xscreensaver-command, Copyright (c) 1991-2009 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_SELECT_H +# include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include /* for CARD32 */ +#include +#include +#include /* for XGetClassHint() */ +#include + +#include "remote.h" + +#ifdef _VROOT_H_ +ERROR! you must not include vroot.h in this file +#endif + +extern char *progname; +extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; +extern Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_EXIT; +extern Atom XA_VROOT, XA_SELECT, XA_DEMO, XA_BLANK, XA_LOCK; + + +static XErrorHandler old_handler = 0; +static Bool got_badwindow = False; +static int +BadWindow_ehandler (Display *dpy, XErrorEvent *error) +{ + if (error->error_code == BadWindow) + { + got_badwindow = True; + return 0; + } + else + { + fprintf (stderr, "%s: ", progname); + if (!old_handler) abort(); + return (*old_handler) (dpy, error); + } +} + + + +static Window +find_screensaver_window (Display *dpy, char **version) +{ + int i; + Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); + Window root2, parent, *kids; + unsigned int nkids; + + if (version) *version = 0; + + if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) + abort (); + if (root != root2) + abort (); + if (parent) + abort (); + if (! (kids && nkids)) + return 0; + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *v; + int status; + + /* We're walking the list of root-level windows and trying to find + the one that has a particular property on it. We need to trap + BadWindows errors while doing this, because it's possible that + some random window might get deleted in the meantime. (That + window won't have been the one we're looking for.) + */ + XSync (dpy, False); + if (old_handler) abort(); + got_badwindow = False; + old_handler = XSetErrorHandler (BadWindow_ehandler); + status = XGetWindowProperty (dpy, kids[i], + XA_SCREENSAVER_VERSION, + 0, 200, False, XA_STRING, + &type, &format, &nitems, &bytesafter, + &v); + XSync (dpy, False); + XSetErrorHandler (old_handler); + old_handler = 0; + + if (got_badwindow) + { + status = BadWindow; + got_badwindow = False; + } + + if (status == Success && type != None) + { + Window ret = kids[i]; + if (version) + *version = (char *) v; + XFree (kids); + return ret; + } + } + + if (kids) XFree (kids); + return 0; +} + + +static int +send_xscreensaver_command (Display *dpy, Atom command, long arg, + Window *window_ret, char **error_ret) +{ + int status = -1; + char *v = 0; + Window window = find_screensaver_window (dpy, &v); + XWindowAttributes xgwa; + char err[2048]; + + if (window_ret) + *window_ret = window; + + if (!window) + { + sprintf (err, "no screensaver is running on display %s", + DisplayString (dpy)); + + if (error_ret) + { + *error_ret = strdup (err); + status = -1; + goto DONE; + } + + if (command == XA_EXIT) + { + /* Don't print an error if xscreensaver is already dead. */ + status = 1; + goto DONE; + } + + fprintf (stderr, "%s: %s\n", progname, err); + status = -1; + goto DONE; + } + + /* Select for property change events, so that we can read the response. */ + XGetWindowAttributes (dpy, window, &xgwa); + XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask); + + if (command == XA_SCREENSAVER_STATUS || + command == XA_SCREENSAVER_VERSION) + { + XClassHint hint; + memset (&hint, 0, sizeof(hint)); + if (!v || !*v) + { + sprintf (err, "version property not set on window 0x%x?", + (unsigned int) window); + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + + status = -1; + goto DONE; + } + + XGetClassHint(dpy, window, &hint); + if (!hint.res_class) + { + sprintf (err, "class hints not set on window 0x%x?", + (unsigned int) window); + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + + status = -1; + goto DONE; + } + + fprintf (stdout, "%s %s", hint.res_class, v); + + if (command != XA_SCREENSAVER_STATUS) + { + fprintf (stdout, "\n"); + } + else + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *dataP = 0; + + if (XGetWindowProperty (dpy, + RootWindow (dpy, 0), + XA_SCREENSAVER_STATUS, + 0, 999, False, XA_INTEGER, + &type, &format, &nitems, &bytesafter, + &dataP) + == Success + && type + && dataP) + { + Atom blanked; + time_t tt; + char *s; + Atom *data = (Atom *) dataP; + + if (type != XA_INTEGER || nitems < 3) + { + STATUS_LOSE: + if (data) free (data); + fprintf (stdout, "\n"); + fflush (stdout); + fprintf (stderr, "bad status format on root window.\n"); + status = -1; + goto DONE; + } + + blanked = (Atom) data[0]; + tt = (time_t) data[1]; + + if (tt <= (time_t) 666000000L) /* early 1991 */ + goto STATUS_LOSE; + + if (blanked == XA_BLANK) + fputs (": screen blanked since ", stdout); + else if (blanked == XA_LOCK) + fputs (": screen locked since ", stdout); + else if (blanked == 0) + /* suggestions for a better way to phrase this are welcome. */ + fputs (": screen non-blanked since ", stdout); + else + /* `blanked' has an unknown value - fail. */ + goto STATUS_LOSE; + + s = ctime(&tt); + if (s[strlen(s)-1] == '\n') + s[strlen(s)-1] = 0; + fputs (s, stdout); + + { + int nhacks = nitems - 2; + Bool any = False; + int i; + for (i = 0; i < nhacks; i++) + if (data[i + 2] > 0) + { + any = True; + break; + } + + if (any && nhacks == 1) + fprintf (stdout, " (hack #%d)\n", (int) data[2]); + else if (any) + { + fprintf (stdout, " (hacks: "); + for (i = 0; i < nhacks; i++) + { + fprintf (stdout, "#%d", (int) data[2 + i]); + if (i != nhacks-1) + fputs (", ", stdout); + } + fputs (")\n", stdout); + } + else + fputs ("\n", stdout); + } + + if (data) free (data); + } + else + { + if (dataP) XFree (dataP); + fprintf (stdout, "\n"); + fflush (stdout); + fprintf (stderr, "no saver status on root window.\n"); + status = -1; + goto DONE; + } + } + + /* No need to read a response for these commands. */ + status = 1; + goto DONE; + } + else + { + XEvent event; + long arg1 = arg; + long arg2 = 0; + + if (arg < 0) + abort(); + else if (arg == 0 && command == XA_SELECT) + abort(); + else if (arg != 0 && command == XA_DEMO) + { + arg1 = 5000; /* version number of the XA_DEMO protocol, */ + arg2 = arg; /* since it didn't use to take an argument. */ + } + + event.xany.type = ClientMessage; + event.xclient.display = dpy; + event.xclient.window = window; + event.xclient.message_type = XA_SCREENSAVER; + event.xclient.format = 32; + memset (&event.xclient.data, 0, sizeof(event.xclient.data)); + event.xclient.data.l[0] = (long) command; + event.xclient.data.l[1] = arg1; + event.xclient.data.l[2] = arg2; + if (! XSendEvent (dpy, window, False, 0L, &event)) + { + sprintf (err, "XSendEvent(dpy, 0x%x ...) failed.\n", + (unsigned int) window); + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + status = -1; + goto DONE; + } + } + + status = 0; + + DONE: + if (v) free (v); + XSync (dpy, 0); + return status; +} + + +static Bool +xscreensaver_command_event_p (Display *dpy, XEvent *event, XPointer arg) +{ + return (event->xany.type == PropertyNotify && + event->xproperty.state == PropertyNewValue && + event->xproperty.atom == XA_SCREENSAVER_RESPONSE); +} + + +static int +xscreensaver_command_response (Display *dpy, Window window, + Bool verbose_p, Bool exiting_p, + char **error_ret) +{ + int sleep_count = 0; + char err[2048]; + XEvent event; + Bool got_event = False; + + while (!(got_event = XCheckIfEvent(dpy, &event, + &xscreensaver_command_event_p, 0)) && + sleep_count++ < 10) + { +# if defined(HAVE_SELECT) + /* Wait for an event, but don't wait longer than 1 sec. Note that we + might do this multiple times if an event comes in, but it wasn't + the event we're waiting for. + */ + int fd = XConnectionNumber(dpy); + fd_set rset; + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + FD_ZERO (&rset); + FD_SET (fd, &rset); + select (fd+1, &rset, 0, 0, &tv); +# else /* !HAVE_SELECT */ + sleep(1); +# endif /* !HAVE_SELECT */ + } + + if (!got_event) + { + sprintf (err, "no response to command."); + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + + return -1; + } + else + { + Status st2; + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *msg = 0; + + XSync (dpy, False); + if (old_handler) abort(); + old_handler = XSetErrorHandler (BadWindow_ehandler); + st2 = XGetWindowProperty (dpy, window, + XA_SCREENSAVER_RESPONSE, + 0, 1024, True, + AnyPropertyType, + &type, &format, &nitems, &bytesafter, + &msg); + XSync (dpy, False); + XSetErrorHandler (old_handler); + old_handler = 0; + + if (got_badwindow) + { + if (exiting_p) + return 0; + + sprintf (err, "xscreensaver window unexpectedly deleted."); + + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + + return -1; + } + + if (st2 == Success && type != None) + { + if (type != XA_STRING || format != 8) + { + sprintf (err, "unrecognized response property."); + + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + + if (msg) XFree (msg); + return -1; + } + else if (!msg || (msg[0] != '+' && msg[0] != '-')) + { + sprintf (err, "unrecognized response message."); + + if (error_ret) + *error_ret = strdup (err); + else + fprintf (stderr, "%s: %s\n", progname, err); + + if (msg) XFree (msg); + return -1; + } + else + { + int ret = (msg[0] == '+' ? 0 : -1); + sprintf (err, "%s: %s\n", progname, (char *) msg+1); + + if (error_ret) + *error_ret = strdup (err); + else if (verbose_p || ret != 0) + fprintf ((ret < 0 ? stderr : stdout), "%s\n", err); + + XFree (msg); + return ret; + } + } + } + + return -1; /* warning suppression: not actually reached */ +} + + +int +xscreensaver_command (Display *dpy, Atom command, long arg, Bool verbose_p, + char **error_ret) +{ + Window w = 0; + int status = send_xscreensaver_command (dpy, command, arg, &w, error_ret); + if (status == 0) + status = xscreensaver_command_response (dpy, w, verbose_p, + (command == XA_EXIT), + error_ret); + + fflush (stdout); + fflush (stderr); + return (status < 0 ? status : 0); +} + + +void +server_xscreensaver_version (Display *dpy, + char **version_ret, + char **user_ret, + char **host_ret) +{ + Window window = find_screensaver_window (dpy, 0); + + Atom type; + int format; + unsigned long nitems, bytesafter; + + if (version_ret) + *version_ret = 0; + if (user_ret) + *user_ret = 0; + if (host_ret) + *host_ret = 0; + + if (!window) + return; + + if (version_ret) + { + unsigned char *v = 0; + XGetWindowProperty (dpy, window, XA_SCREENSAVER_VERSION, 0, 1, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, &v); + if (v) + { + *version_ret = strdup ((char *) v); + XFree (v); + } + } + + if (user_ret || host_ret) + { + unsigned char *id = 0; + const char *user = 0; + const char *host = 0; + + XGetWindowProperty (dpy, window, XA_SCREENSAVER_ID, 0, 512, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, &id); + if (id && *id) + { + const char *old_tag = " on host "; + const char *s = strstr ((char *) id, old_tag); + if (s) + { + /* found ID of the form "1234 on host xyz". */ + user = 0; + host = s + strlen (old_tag); + } + else + { + char *o = 0, *p = 0, *c = 0; + o = strchr ((char *) id, '('); + if (o) p = strchr (o, '@'); + if (p) c = strchr (p, ')'); + if (c) + { + /* found ID of the form "1234 (user@host)". */ + user = o+1; + host = p+1; + *p = 0; + *c = 0; + } + } + + } + + if (user && *user && *user != '?') + *user_ret = strdup (user); + else + *user_ret = 0; + + if (host && *host && *host != '?') + *host_ret = strdup (host); + else + *host_ret = 0; + + if (id) + XFree (id); + } +} diff --git a/driver/remote.h b/driver/remote.h new file mode 100644 index 00000000..e1db3517 --- /dev/null +++ b/driver/remote.h @@ -0,0 +1,24 @@ +/* xscreensaver-command, Copyright (c) 1991-1998 + * by 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_REMOTE_H_ +#define _XSCREENSAVER_REMOTE_H_ + +extern int xscreensaver_command (Display *dpy, Atom command, long arg, + Bool verbose_p, char **error_ret); + +extern void server_xscreensaver_version (Display *dpy, + char **version_ret, + char **user_ret, + char **host_ret); + +#endif /* _XSCREENSAVER_REMOTE_H_ */ diff --git a/driver/screens.c b/driver/screens.c new file mode 100644 index 00000000..52320d65 --- /dev/null +++ b/driver/screens.c @@ -0,0 +1,1077 @@ +/* screens.c --- dealing with RANDR, Xinerama, and VidMode Viewports. + * xscreensaver, Copyright (c) 1991-2008 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. + */ + +/* There are a bunch of different mechanisms for multiple monitors + * available in X. XScreenSaver needs to care about this for two + * reasons: first, to ensure that all visible areas go black; and + * second, so that the windows of screen savers exactly fill the + * glass of each monitor (instead of one saver spanning multiple + * monitors, or a monitor displaying only a sub-rectangle of the + * screen saver.) + * + * 1) Multi-screen: + * + * This is the original way. Each monitor gets its own display + * number. :0.0 is the first one, :0.1 is the next, etc. The + * value of $DISPLAY determines which screen windows open on by + * default. A single app can open windows on multiple screens + * with the same display connection, but windows cannot be moved + * from one screen to another. The mouse can be moved from one + * screen to another, though. Screens may be different depths + * (e.g., one can be TrueColor and one can be PseudoColor.) + * Screens cannot be resized or moved without restarting X. + * + * Everyone hates this way of doing things because of the + * inability to move a window from one screen to another without + * restarting the application. + * + * 2) Xinerama: + * + * There is a single giant root window that spans all the + * monitors. All monitors are the same depth, and windows can be + * moved around. Applications can learn which rectangles are + * actually visible on monitors by querying the Xinerama server + * extension. (If you don't do that, you end up with dialog + * boxes that try to appear in the middle of the screen actually + * spanning the gap between two monitors.) + * + * Xinerama doesn't work with DRI, which means that if you use + * it, you lose hardware acceleration on OpenGL programs. Also, + * screens can't be resized or moved without restarting X. + * + * 3) Vidmode Viewports: + * + * With this extension, the root window can be bigger than the + * monitor. Moving the mouse near the edges of the screen + * scrolls around, like a pan-and-scan movie. There can also be + * a hot key for changing the monitor's resolution (zooming + * in/out). + * + * Trying to combine this with Xinerama crashes the server, so + * you can only use this if you have only a single screen, or are + * in old-multi-screen mode. + * + * Also, half the time it doesn't work at all: it tends to lie + * about the size of the rectangle in use. + * + * 4) RANDR 1.0: + * + * The first version of the "Resize and Rotate" extension let you + * change the resolution of a screen on the fly. The root window + * would actually resize. However, it was also incompatible with + * Xinerama (did it crash, or just do nothing? I can't remember) + * so you needed to be in single-screen or old multi-screen mode. + * I believe RANDR could co-exist with Vidmode Viewports, but I'm + * not sure. + * + * 5) RANDR 1.2: + * + * Finally, RANDR added the functionality of Xinerama, plus some. + * Each X screen (in the sense of #1, "multi-screen") can have a + * number of sub-rectangles that are displayed on monitors, and + * each of those sub-rectangles can be displayed on more than one + * monitor. So it's possible (I think) to have a hybrid of + * multi-screen and Xinerama (e.g., to have two monitors running + * in one depth, and three monitors running in another?) + * Typically though, there will be a single X screen, with + * Xinerama-like division of that large root window onto multiple + * monitors. Also everything's dynamic: monitors can be added, + * removed, and resized at runtime. + * + * I believe that as of RANDR 1.2, the Xinerama extension still + * exists but only as a compatiblity layer: it's actually + * returning data from the RANDR extension. + * + * Though RANDR 1.2 allows the same image to be cloned onto more + * than one monitor, and also allows one monitor to show a + * subsection of something on another monitor (e.g., the + * rectangles can be enclosed or overlap). Since there's no way + * to put seperate savers on those duplicated-or-overlapping + * monitors, xscreensaver just ignores them (which allows them to + * display duplicates or overlaps). + * + * 5a) Nvidia fucks it up: + * + * Nvidia drivers as of Aug 2008 running in "TwinView" mode + * apparently report correct screen geometry via Xinerama, but + * report one giant screen via RANDR. The response from the + * nvidia developers is, "we don't support RANDR, use Xinerama + * instead." Which is a seriously lame answer. So, xscreensaver + * has to query *both* extensions, and make a guess as to which + * is to be believed. + * + * 5b) Also sometimes RANDR says stupid shit like, "You have one + * screen, and it has no available orientations or sizes." + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#ifdef HAVE_RANDR +# include +#endif /* HAVE_RANDR */ + +#ifdef HAVE_XINERAMA +# include +#endif /* HAVE_XINERAMA */ + +#ifdef HAVE_XF86VMODE +# include +#endif /* HAVE_XF86VMODE */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" +#include "visual.h" + + +typedef enum { S_SANE, S_ENCLOSED, S_DUPLICATE, S_OVERLAP, + S_OFFSCREEN, S_DISABLED } monitor_sanity; + +/* 'typedef monitor' is in types.h */ +struct _monitor { + int id; + char *desc; + Screen *screen; + int x, y, width, height; + monitor_sanity sanity; /* I'm not crazy you're the one who's crazy */ + int enemy; /* which monitor it overlaps or duplicates */ + char *err; /* msg to print at appropriate later time; + exists only on monitor #0. */ +}; + +static Bool layouts_differ_p (monitor **a, monitor **b); + + +static void +free_monitors (monitor **monitors) +{ + monitor **m2 = monitors; + if (! monitors) return; + while (*m2) + { + if ((*m2)->desc) free ((*m2)->desc); + if ((*m2)->err) free ((*m2)->err); + free (*m2); + m2++; + } + free (monitors); +} + + +static char * +append (char *s1, const char *s2) +{ + char *s = (char *) malloc ((s1 ? strlen(s1) : 0) + + (s2 ? strlen(s2) : 0) + 3); + *s = 0; + if (s1) strcat (s, s1); + if (s1 && s2) strcat (s, "\n"); + if (s2) strcat (s, s2); + if (s1) free (s1); + return s; +} + + +#ifdef HAVE_XINERAMA + +static monitor ** +xinerama_scan_monitors (Display *dpy, char **errP) +{ + Screen *screen = DefaultScreenOfDisplay (dpy); + int event, error, nscreens, i; + XineramaScreenInfo *xsi; + monitor **monitors; + + if (! XineramaQueryExtension (dpy, &event, &error)) + return 0; + + if (! XineramaIsActive (dpy)) + return 0; + + xsi = XineramaQueryScreens (dpy, &nscreens); + if (!xsi) return 0; + + monitors = (monitor **) calloc (nscreens + 1, sizeof(*monitors)); + if (!monitors) return 0; + + for (i = 0; i < nscreens; i++) + { + monitor *m = (monitor *) calloc (1, sizeof (monitor)); + monitors[i] = m; + m->id = i; + m->screen = screen; + m->x = xsi[i].x_org; + m->y = xsi[i].y_org; + m->width = xsi[i].width; + m->height = xsi[i].height; + } + return monitors; +} + +#endif /* HAVE_XINERAMA */ + + +#ifdef HAVE_XF86VMODE + +static monitor ** +vidmode_scan_monitors (Display *dpy, char **errP) +{ + int event, error, nscreens, i; + monitor **monitors; + + /* Note that XF86VidModeGetViewPort() tends to be full of lies on laptops + that have a docking station or external monitor that runs in a different + resolution than the laptop's screen: + + http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=81593 + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=208417 + http://bugs.xfree86.org/show_bug.cgi?id=421 + + Presumably this is fixed by using RANDR instead of VidMode. + */ + +# ifdef HAVE_XINERAMA + /* Attempts to use the VidMode extension when the Xinerama extension is + active can result in a server crash! Yay! */ + if (XQueryExtension (dpy, "XINERAMA", &error, &event, &error)) + return 0; +# endif /* !HAVE_XINERAMA */ + + if (! XF86VidModeQueryExtension (dpy, &event, &error)) + return 0; + + nscreens = ScreenCount (dpy); + monitors = (monitor **) calloc (nscreens + 1, sizeof(*monitors)); + if (!monitors) return 0; + + for (i = 0; i < nscreens; i++) + { + monitor *m = (monitor *) calloc (1, sizeof (monitor)); + XF86VidModeModeLine ml; + int dot; + Screen *screen = ScreenOfDisplay (dpy, i); + + monitors[i] = m; + m->id = i; + m->screen = screen; + + if (! safe_XF86VidModeGetViewPort (dpy, i, &m->x, &m->y)) + m->x = m->y = -1; + + if (XF86VidModeGetModeLine (dpy, i, &dot, &ml)) + { + m->width = ml.hdisplay; + m->height = ml.vdisplay; + } + + /* Apparently, though the server stores the X position in increments of + 1 pixel, it will only make changes to the *display* in some other + increment. With XF86_SVGA on a Thinkpad, the display only updates + in multiples of 8 pixels when in 8-bit mode, and in multiples of 4 + pixels in 16-bit mode. I don't know what it does in 24- and 32-bit + mode, because I don't have enough video memory to find out. + + I consider it a bug that XF86VidModeGetViewPort() is telling me the + server's *target* scroll position rather than the server's *actual* + scroll position. David Dawes agrees, and says they may fix this in + XFree86 4.0, but it's notrivial. + + He also confirms that this behavior is server-dependent, so the + actual scroll position cannot be reliably determined by the client. + So... that means the only solution is to provide a ``sandbox'' + around the blackout window -- we make the window be up to N pixels + larger than the viewport on both the left and right sides. That + means some part of the outer edges of each hack might not be + visible, but screw it. + + I'm going to guess that 16 pixels is enough, and that the Y dimension + doesn't have this problem. + + The drawback of doing this, of course, is that some of the screenhacks + will still look pretty stupid -- for example, "slidescreen" will cut + off the left and right edges of the grid, etc. + */ +# define FUDGE 16 + if (m->x > 0 && m->x < m->width - ml.hdisplay) + { + /* Not at left edge or right edge: + Round X position down to next lower multiple of FUDGE. + Increase width by 2*FUDGE in case some server rounds up. + */ + m->x = ((m->x - 1) / FUDGE) * FUDGE; + m->width += (FUDGE * 2); + } +# undef FUDGE + } + + return monitors; +} + +#endif /* HAVE_XF86VMODE */ + + +#ifdef HAVE_RANDR + +static monitor ** +randr_scan_monitors (Display *dpy, char **errP) +{ + int event, error, major, minor, nscreens, i, j; + monitor **monitors; + Bool new_randr_p = False; + + if (! XRRQueryExtension (dpy, &event, &error)) + return 0; + + if (! XRRQueryVersion (dpy, &major, &minor)) + return 0; + + if (major <= 0) /* Protocol was still in flux back then -- fuck it. */ + return 0; + +# ifdef HAVE_RANDR_12 + new_randr_p = (major > 1 || (major == 1 && minor >= 2)); +# endif + + if (! new_randr_p) + /* RANDR 1.0 -- no Xinerama-like virtual screens. */ + nscreens = ScreenCount (dpy); + else /* RANDR 1.2 or newer -- built-in Xinerama */ + { +# ifdef HAVE_RANDR_12 + int xsc = ScreenCount (dpy); + nscreens = 0; + /* Add up the virtual screens on each X screen. */ + for (i = 0; i < xsc; i++) + { + XRRScreenResources *res = + XRRGetScreenResources (dpy, RootWindow (dpy, i)); + nscreens += res->noutput; + XRRFreeScreenResources (res); + } +# endif /* HAVE_RANDR_12 */ + } + + if (nscreens <= 0) + { + *errP = append (*errP, + "WARNING: RANDR reported no screens! Ignoring it."); + return 0; + } + + monitors = (monitor **) calloc (nscreens + 1, sizeof(*monitors)); + if (!monitors) return 0; + + for (i = 0, j = 0; i < ScreenCount (dpy); i++) + { + Screen *screen = ScreenOfDisplay (dpy, i); + + if (! new_randr_p) /* RANDR 1.0 */ + { + XRRScreenConfiguration *rrc; + monitor *m = (monitor *) calloc (1, sizeof (monitor)); + monitors[i] = m; + m->screen = screen; + m->id = i; + + rrc = XRRGetScreenInfo (dpy, RootWindowOfScreen (screen)); + if (rrc) + { + SizeID size = -1; + Rotation rot = ~0; + XRRScreenSize *rrsizes; + int nsizes = 0; + + size = XRRConfigCurrentConfiguration (rrc, &rot); + rrsizes = XRRConfigSizes (rrc, &nsizes); + + if (nsizes <= 0) /* WTF? Shouldn't happen but does. */ + { + m->width = DisplayWidth (dpy, i); + m->height = DisplayHeight (dpy, i); + } + else if (rot & (RR_Rotate_90|RR_Rotate_270)) + { + m->width = rrsizes[size].height; + m->height = rrsizes[size].width; + } + else + { + m->width = rrsizes[size].width; + m->height = rrsizes[size].height; + } + + /* don't free 'rrsizes' */ + XRRFreeScreenConfigInfo (rrc); + } + } + else /* RANDR 1.2 or newer */ + { +# ifdef HAVE_RANDR_12 + int k; + XRRScreenResources *res = + XRRGetScreenResources (dpy, RootWindowOfScreen (screen)); + for (k = 0; k < res->noutput; k++, j++) + { + monitor *m = (monitor *) calloc (1, sizeof (monitor)); + XRROutputInfo *rroi = XRRGetOutputInfo (dpy, res, + res->outputs[k]); + RRCrtc crtc = (rroi->crtc ? rroi->crtc : + rroi->ncrtc ? rroi->crtcs[0] : 0); + XRRCrtcInfo *crtci = (crtc ? XRRGetCrtcInfo(dpy, res, crtc) : 0); + + monitors[j] = m; + m->screen = screen; + m->id = (i * 1000) + j; + m->desc = (rroi->name ? strdup (rroi->name) : 0); + + if (crtci) + { + /* Note: if the screen is rotated, XRRConfigSizes contains + the unrotated WxH, but XRRCrtcInfo contains rotated HxW. + */ + m->x = crtci->x; + m->y = crtci->y; + m->width = crtci->width; + m->height = crtci->height; + } + + if (rroi->connection == RR_Disconnected) + m->sanity = S_DISABLED; + /* #### do the same for RR_UnknownConnection? */ + + if (crtci) + XRRFreeCrtcInfo (crtci); + XRRFreeOutputInfo (rroi); + } + XRRFreeScreenResources (res); +# endif /* HAVE_RANDR_12 */ + } + } + + /* Work around more fucking brain damage. */ + { + int ok = 0; + int i = 0; + while (monitors[i]) + { + if (monitors[i]->width != 0 && monitors[i]->height != 0) + ok++; + i++; + } + if (! ok) + { + *errP = append (*errP, + "WARNING: RANDR says all screens are 0x0! Ignoring it."); + free_monitors (monitors); + monitors = 0; + } + } + + return monitors; +} + +#endif /* HAVE_RANDR */ + + +static monitor ** +basic_scan_monitors (Display *dpy, char **errP) +{ + int nscreens = ScreenCount (dpy); + int i; + monitor **monitors = (monitor **) calloc (nscreens + 1, sizeof(*monitors)); + if (!monitors) return 0; + + for (i = 0; i < nscreens; i++) + { + Screen *screen = ScreenOfDisplay (dpy, i); + monitor *m = (monitor *) calloc (1, sizeof (monitor)); + monitors[i] = m; + m->id = i; + m->screen = screen; + m->x = 0; + m->y = 0; + m->width = WidthOfScreen (screen); + m->height = HeightOfScreen (screen); + } + return monitors; +} + + +#if defined(HAVE_RANDR) && defined(HAVE_XINERAMA) + +/* From: Aaron Plattner + Date: August 7, 2008 10:21:25 AM PDT + To: linux-bugs@nvidia.com + + The NVIDIA X driver does not yet support RandR 1.2. The X server has + a compatibility layer in it that allows RandR 1.2 clients to talk to + RandR 1.1 drivers through an RandR 1.2 pseudo-output called "default". + This reports the total combined resolution of the TwinView display, + since it doesn't have any visibility into TwinView metamodes. There + is no way for the driver to prevent the server from turning on this + compatibility layer. + + The intention is for X client applications to continue to use the + Xinerama extension to query the screen geometry. RandR 1.2 reports + its own Xinerama info for this purpose. I would recommend against + modifying xscreensaver to try to get this information from RandR. + */ +static monitor ** +randr_versus_xinerama_fight (Display *dpy, monitor **randr_monitors, + char **errP) +{ + monitor **xinerama_monitors; + + if (!randr_monitors) + return 0; + + xinerama_monitors = xinerama_scan_monitors (dpy, errP); + if (!xinerama_monitors) + return randr_monitors; + + if (! layouts_differ_p (randr_monitors, xinerama_monitors)) + { + free_monitors (xinerama_monitors); + return randr_monitors; + } + else if ( randr_monitors[0] && !randr_monitors[1] && /* 1 monitor */ + xinerama_monitors[0] && xinerama_monitors[1]) /* >1 monitor */ + { + *errP = append (*errP, + "WARNING: RANDR reports 1 screen but Xinerama\n" + "\t\treports multiple. Believing Xinerama."); + free_monitors (randr_monitors); + return xinerama_monitors; + } + else + { + *errP = append (*errP, + "WARNING: RANDR and Xinerama report different\n" + "\t\tscreen layouts! Believing RANDR."); + free_monitors (xinerama_monitors); + return randr_monitors; + } +} + +#endif /* HAVE_RANDR && HAVE_XINERAMA */ + + +#ifdef DEBUG_MULTISCREEN + +/* If DEBUG_MULTISCREEN is defined, then in "-debug" mode, xscreensaver + will pretend that it is changing the number of connected monitors + every few seconds, using the geometries in the following list, + for stress-testing purposes. + */ +static monitor ** +debug_scan_monitors (Display *dpy, char **errP) +{ + static const char * const geoms[] = { + "1600x1028+0+22", + "1024x768+0+22", + "800x600+0+22", + "800x600+0+22,800x600+800+22", + "800x600+0+22,800x600+800+22,800x600+300+622", + "800x600+0+22,800x600+800+22,800x600+0+622,800x600+800+622", + "640x480+0+22,640x480+640+22,640x480+0+502,640x480+640+502", + "640x480+240+22,640x480+0+502,640x480+640+502", + "640x480+0+200,640x480+640+200", + "800x600+400+22", + "320x200+0+22,320x200+320+22,320x200+640+22,320x200+960+22,320x200+0+222,320x200+320+222,320x200+640+222,320x200+960+222,320x200+0+422,320x200+320+422,320x200+640+422,320x200+960+422,320x200+0+622,320x200+320+622,320x200+640+622,320x200+960+622,320x200+0+822,320x200+320+822,320x200+640+822,320x200+960+822" + }; + static int index = 0; + monitor **monitors = (monitor **) calloc (100, sizeof(*monitors)); + int nscreens = 0; + Screen *screen = DefaultScreenOfDisplay (dpy); + + char *s = strdup (geoms[index]); + char *token = strtok (s, ","); + while (token) + { + monitor *m = calloc (1, sizeof (monitor)); + char c; + m->id = nscreens; + m->screen = screen; + if (4 != sscanf (token, "%dx%d+%d+%d%c", + &m->width, &m->height, &m->x, &m->y, &c)) + abort(); + m->width -= 2; + m->height -= 2; + monitors[nscreens++] = m; + token = strtok (0, ","); + } + free (s); + + index = (index+1) % countof(geoms); + return monitors; +} + +#endif /* DEBUG_MULTISCREEN */ + + +#ifdef QUAD_MODE +static monitor ** +quadruple (monitor **monitors, Bool debug_p, char **errP) +{ + int i, j, count = 0; + monitor **monitors2; + while (monitors[count]) + count++; + monitors2 = (monitor **) calloc (count * 4 + 1, sizeof(*monitors)); + if (!monitors2) abort(); + + for (i = 0, j = 0; i < count; i++) + { + int k; + for (k = 0; k < 4; k++) + { + monitors2[j+k] = (monitor *) calloc (1, sizeof (monitor)); + *monitors2[j+k] = *monitors[i]; + monitors2[j+k]->width /= (debug_p ? 4 : 2); + monitors2[j+k]->height /= 2; + monitors2[j+k]->id = (monitors[i]->id * 4) + k; + monitors2[j+k]->name = (monitors[i]->name + ? strdup (monitors[i]->name) : 0); + } + monitors2[j+1]->x += monitors2[j]->width; + monitors2[j+2]->y += monitors2[j]->height; + monitors2[j+3]->x += monitors2[j]->width; + monitors2[j+3]->y += monitors2[j]->height; + j += 4; + } + + free_monitors (monitors); + return monitors2; +} +#endif /* QUAD_MODE */ + + +static monitor ** +scan_monitors (saver_info *si) +{ + saver_preferences *p = &si->prefs; + monitor **monitors = 0; + char *err = 0; + +# ifdef DEBUG_MULTISCREEN + if (! monitors) monitors = debug_scan_monitors (si->dpy, &err); +# endif + +# ifdef HAVE_RANDR + if (! p->getviewport_full_of_lies_p) + if (! monitors) monitors = randr_scan_monitors (si->dpy, &err); + +# ifdef HAVE_XINERAMA + monitors = randr_versus_xinerama_fight (si->dpy, monitors, &err); +# endif +# endif /* HAVE_RANDR */ + +# ifdef HAVE_XF86VMODE + if (! monitors) monitors = vidmode_scan_monitors (si->dpy, &err); +# endif + +# ifdef HAVE_XINERAMA + if (! monitors) monitors = xinerama_scan_monitors (si->dpy, &err); +# endif + + if (! monitors) monitors = basic_scan_monitors (si->dpy, &err); + +# ifdef QUAD_MODE + if (p->quad_p) + monitors = quadruple (monitors, p->debug_p, &err); +# endif + + if (monitors && err) monitors[0]->err = err; + + return monitors; +} + + +static Bool +monitors_overlap_p (monitor *a, monitor *b) +{ + /* Two rectangles overlap if the max of the tops is less than the + min of the bottoms and the max of the lefts is less than the min + of the rights. + */ +# undef MAX +# undef MIN +# define MAX(A,B) ((A)>(B)?(A):(B)) +# define MIN(A,B) ((A)<(B)?(A):(B)) + + int maxleft = MAX(a->x, b->x); + int maxtop = MAX(a->y, b->y); + int minright = MIN(a->x + a->width - 1, b->x + b->width); + int minbot = MIN(a->y + a->height - 1, b->y + b->height); + return (maxtop < minbot && maxleft < minright); +} + + +static Bool +plausible_aspect_ratio_p (monitor **monitors) +{ + /* Modern wide-screen monitors come in the following aspect ratios: + + One monitor: If you tack a 640x480 monitor + onto the right, the ratio is: + 16 x 9 --> 1.78 + 852 x 480 --> 1.77 852+640 x 480 --> 3.11 "SD 480p" + 1280 x 720 --> 1.78 1280+640 x 720 --> 2.67 "HD 720p" + 1280 x 920 --> 1.39 1280+640 x 920 --> 2.09 + 1366 x 768 --> 1.78 1366+640 x 768 --> 2.61 "HD 768p" + 1440 x 900 --> 1.60 1440+640 x 900 --> 2.31 + 1680 x 1050 --> 1.60 1680+640 x 1050 --> 2.21 + 1690 x 1050 --> 1.61 1690+640 x 1050 --> 2.22 + 1920 x 1080 --> 1.78 1920+640 x 1080 --> 2.37 "HD 1080p" + 1920 x 1200 --> 1.60 1920+640 x 1200 --> 2.13 + 2560 x 1600 --> 1.60 2560+640 x 1600 --> 2.00 + + So that implies that if we ever see an aspect ratio >= 2.0, + we can be pretty sure that the X server is lying to us, and + that's actually two monitors, not one. + */ + if (monitors[0] && !monitors[1] && /* exactly 1 monitor */ + monitors[0]->height && + monitors[0]->width / (double) monitors[0]->height >= 1.9) + return False; + else + return True; +} + + +/* Mark the ones that overlap, etc. + */ +static void +check_monitor_sanity (monitor **monitors) +{ + int i, j, count = 0; + + while (monitors[count]) + count++; + +# define X1 monitors[i]->x +# define X2 monitors[j]->x +# define Y1 monitors[i]->y +# define Y2 monitors[j]->y +# define W1 monitors[i]->width +# define W2 monitors[j]->width +# define H1 monitors[i]->height +# define H2 monitors[j]->height + + /* If a monitor is enclosed by any other monitor, that's insane. + */ + for (i = 0; i < count; i++) + for (j = 0; j < count; j++) + if (i != j && + monitors[i]->sanity == S_SANE && + monitors[j]->sanity == S_SANE && + monitors[i]->screen == monitors[j]->screen && + X2 >= X1 && + Y2 >= Y1 && + (X2+W2) <= (X1+W1) && + (Y2+H2) <= (Y1+H1)) + { + if (X1 == X2 && + Y1 == Y2 && + W1 == W2 && + H1 == H2) + monitors[j]->sanity = S_DUPLICATE; + else + monitors[j]->sanity = S_ENCLOSED; + monitors[j]->enemy = i; + } + + /* After checking for enclosure, check for other lossage against earlier + monitors. We do enclosure first so that we make sure to pick the + larger one. + */ + for (i = 0; i < count; i++) + for (j = 0; j < i; j++) + { + if (monitors[i]->sanity != S_SANE) continue; /* already marked */ + if (monitors[j]->sanity != S_SANE) continue; + if (monitors[i]->screen != monitors[j]->screen) continue; + + if (monitors_overlap_p (monitors[i], monitors[j])) + { + monitors[i]->sanity = S_OVERLAP; + monitors[i]->enemy = j; + } + } + + /* Finally, make sure all monitors have sane positions and sizes. + Xinerama sometimes reports 1024x768 VPs at -1936862040, -1953705044. + */ + for (i = 0; i < count; i++) + { + if (monitors[i]->sanity != S_SANE) continue; /* already marked */ + if (X1 < 0 || Y1 < 0 || + W1 <= 0 || H1 <= 0 || + X1+W1 >= 0x7FFF || Y1+H1 >= 0x7FFF) + { + monitors[i]->sanity = S_OFFSCREEN; + monitors[i]->enemy = 0; + } + } + +# undef X1 +# undef X2 +# undef Y1 +# undef Y2 +# undef W1 +# undef W2 +# undef H1 +# undef H2 +} + + +static Bool +layouts_differ_p (monitor **a, monitor **b) +{ + if (!a || !b) return True; + while (1) + { + if (!*a) break; + if (!*b) break; + if ((*a)->screen != (*b)->screen || + (*a)->x != (*b)->x || + (*a)->y != (*b)->y || + (*a)->width != (*b)->width || + (*a)->height != (*b)->height) + return True; + a++; + b++; + } + if (*a) return True; + if (*b) return True; + + return False; +} + + +void +describe_monitor_layout (saver_info *si) +{ + monitor **monitors = si->monitor_layout; + int count = 0; + int good_count = 0; + int bad_count = 0; + int implausible_p = !plausible_aspect_ratio_p (monitors); + + while (monitors[count]) + { + if (monitors[count]->sanity == S_SANE) + good_count++; + else + bad_count++; + count++; + } + + if (monitors[0]->err) /* deferred error msg */ + { + char *token = strtok (monitors[0]->err, "\n"); + while (token) + { + fprintf (stderr, "%s: %s\n", blurb(), token); + token = strtok (0, "\n"); + } + free (monitors[0]->err); + monitors[0]->err = 0; + } + + if (count == 0) + fprintf (stderr, "%s: no screens!\n", blurb()); + else + { + int i; + fprintf (stderr, "%s: screens in use: %d\n", blurb(), good_count); + for (i = 0; i < count; i++) + { + monitor *m = monitors[i]; + if (m->sanity != S_SANE) continue; + fprintf (stderr, "%s: %3d/%d: %dx%d+%d+%d", + blurb(), m->id, screen_number (m->screen), + m->width, m->height, m->x, m->y); + if (m->desc && *m->desc) fprintf (stderr, " (%s)", m->desc); + fprintf (stderr, "\n"); + } + if (bad_count > 0) + { + fprintf (stderr, "%s: rejected screens: %d\n", blurb(), bad_count); + for (i = 0; i < count; i++) + { + monitor *m = monitors[i]; + monitor *e = monitors[m->enemy]; + if (m->sanity == S_SANE) continue; + fprintf (stderr, "%s: %3d/%d: %dx%d+%d+%d", + blurb(), m->id, screen_number (m->screen), + m->width, m->height, m->x, m->y); + if (m->desc && *m->desc) fprintf (stderr, " (%s)", m->desc); + fprintf (stderr, " -- "); + switch (m->sanity) + { + case S_SANE: abort(); break; + case S_ENCLOSED: + fprintf (stderr, "enclosed by %d (%dx%d+%d+%d)\n", + e->id, e->width, e->height, e->x, e->y); + break; + case S_DUPLICATE: + fprintf (stderr, "duplicate of %d\n", e->id); + break; + case S_OVERLAP: + fprintf (stderr, "overlaps %d (%dx%d+%d+%d)\n", + e->id, e->width, e->height, e->x, e->y); + break; + case S_OFFSCREEN: + fprintf (stderr, "off screen (%dx%d)\n", + WidthOfScreen (e->screen), + HeightOfScreen (e->screen)); + break; + case S_DISABLED: + fprintf (stderr, "output disabled\n"); + break; + } + } + } + + if (implausible_p) + fprintf (stderr, + "%s: WARNING: single screen aspect ratio is %dx%d = %.2f\n" + "%s: probable X server bug in Xinerama/RANDR!\n", + blurb(), monitors[0]->width, monitors[0]->height, + monitors[0]->width / (double) monitors[0]->height, + blurb()); + } +} + + +/* Synchronize the contents of si->ssi to the current state of the monitors. + Doesn't change anything if nothing has changed; otherwise, alters and + reuses existing saver_screen_info structs as much as possible. + Returns True if anything changed. + */ +Bool +update_screen_layout (saver_info *si) +{ + monitor **monitors = scan_monitors (si); + int count = 0; + int good_count = 0; + int i, j; + int seen_screens[100] = { 0, }; + + if (! layouts_differ_p (monitors, si->monitor_layout)) + { + free_monitors (monitors); + return False; + } + + free_monitors (si->monitor_layout); + si->monitor_layout = monitors; + check_monitor_sanity (si->monitor_layout); + + while (monitors[count]) + { + if (monitors[count]->sanity == S_SANE) + good_count++; + count++; + } + + if (si->ssi_count == 0) + { + si->ssi_count = 10; + si->screens = (saver_screen_info *) + calloc (sizeof(*si->screens), si->ssi_count); + } + + if (si->ssi_count <= good_count) + { + si->ssi_count = good_count + 10; + si->screens = (saver_screen_info *) + realloc (si->screens, sizeof(*si->screens) * si->ssi_count); + memset (si->screens + si->nscreens, 0, + sizeof(*si->screens) * (si->ssi_count - si->nscreens)); + } + + if (! si->screens) abort(); + + si->nscreens = good_count; + + /* Regenerate the list of GL visuals as needed. */ + if (si->best_gl_visuals) + free (si->best_gl_visuals); + si->best_gl_visuals = 0; + + for (i = 0, j = 0; i < count; i++) + { + monitor *m = monitors[i]; + saver_screen_info *ssi = &si->screens[j]; + Screen *old_screen = ssi->screen; + int sn; + if (monitors[i]->sanity != S_SANE) continue; + + ssi->global = si; + ssi->number = j; + + sn = screen_number (m->screen); + ssi->screen = m->screen; + ssi->real_screen_number = sn; + ssi->real_screen_p = (seen_screens[sn] == 0); + seen_screens[sn]++; + + ssi->default_visual = + get_visual_resource (ssi->screen, "visualID", "VisualID", False); + ssi->current_visual = ssi->default_visual; + ssi->current_depth = visual_depth (ssi->screen, ssi->current_visual); + + /* If the screen changed (or if this is the first time) we need + a new toplevel shell for this screen's depth. + */ + if (ssi->screen != old_screen) + initialize_screen_root_widget (ssi); + + ssi->last_poll_mouse.root_x = -1; + ssi->last_poll_mouse.root_y = -1; + + ssi->x = m->x; + ssi->y = m->y; + ssi->width = m->width; + ssi->height = m->height; + +# ifndef DEBUG_MULTISCREEN + { + saver_preferences *p = &si->prefs; + if (p->debug_p +# ifdef QUAD_MODE + && !p->quad_p +# endif + ) + ssi->width /= 2; + } +# endif + + j++; + } + + si->default_screen = &si->screens[0]; + return True; +} diff --git a/driver/screensaver-properties.desktop.in b/driver/screensaver-properties.desktop.in new file mode 100644 index 00000000..de425279 --- /dev/null +++ b/driver/screensaver-properties.desktop.in @@ -0,0 +1,8 @@ +[Desktop Entry] +Exec=xscreensaver-demo +Icon=xscreensaver +Terminal=false +_Name=Screensaver +_Comment=Change screensaver properties +Type=Application +Categories=Settings;DesktopSettings;Security;X-XFCE; diff --git a/driver/setuid.c b/driver/setuid.c new file mode 100644 index 00000000..3ac78e4f --- /dev/null +++ b/driver/setuid.c @@ -0,0 +1,361 @@ +/* setuid.c --- management of runtime privileges. + * xscreensaver, Copyright (c) 1993-1998, 2005 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include /* not used for much... */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" + +#ifndef EPERM +#include +#endif + +#include /* for getpwnam() and struct passwd */ +#include /* for getgrgid() and struct group */ + +static const char * +uid_gid_string (uid_t uid, gid_t gid) +{ + static char buf[255]; + struct passwd *p = 0; + struct group *g = 0; + p = getpwuid (uid); + g = getgrgid (gid); + sprintf (buf, "%.100s/%.100s (%ld/%ld)", + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???"), + (long) uid, (long) gid); + return buf; +} + + +void +describe_uids (saver_info *si, FILE *out) +{ + uid_t uid = getuid(); + gid_t gid = getgid(); + uid_t euid = geteuid(); + gid_t egid = getegid(); + char *s1 = strdup (uid_gid_string (uid, gid)); + char *s2 = strdup (uid_gid_string (euid, egid)); + + if (si->orig_uid && *si->orig_uid && + (!!strcmp (si->orig_uid, s1) || + !!strcmp (si->orig_uid, s2))) + fprintf (out, "%s: initial effective uid/gid was %s\n", blurb(), + si->orig_uid); + + fprintf (out, "%s: running as %s", blurb(), s1); + if (uid != euid || gid != egid) + fprintf (out, "; effectively %s", s2); + fprintf(out, "\n"); + free(s1); + free(s2); +} + + +/* Returns true if we need to call setgroups(). + + Without calling setgroups(), the process will retain any supplementary + gids associated with the uid, e.g.: + + % groups root + root : root bin daemon sys adm disk wheel + + However, setgroups() can only be called by root, and returns EPERM + for other users even if the call would be a no-op (e.g., setting the + group list to the current list.) So, to avoid that spurious error, + before calling setgroups() we first check whether the current list + of groups contains only one element, our target group. If so, we + don't need to call setgroups(). + */ +static int +setgroups_needed_p (uid_t target_group) +{ + gid_t groups[1024]; + int n, size; + size = sizeof(groups) / sizeof(gid_t); + n = getgroups (size - 1, groups); + if (n < 0) + { + char buf [1024]; + sprintf (buf, "%s: getgroups(%ld, ...)", blurb(), (long int)(size - 1)); + perror (buf); + return 1; + } + else if (n == 0) /* an empty list means only egid is in effect. */ + return 0; + else if (n == 1 && groups[0] == target_group) /* one element, the target */ + return 0; + else /* more than one, or the wrong one. */ + return 1; +} + + +static int +set_ids_by_number (uid_t uid, gid_t gid, char **message_ret) +{ + int uid_errno = 0; + int gid_errno = 0; + int sgs_errno = 0; + struct passwd *p = getpwuid (uid); + struct group *g = getgrgid (gid); + + if (message_ret) + *message_ret = 0; + + /* Rumor has it that some implementations of of setuid() do nothing + when called with -1; therefore, if the "nobody" user has a uid of + -1, then that would be Really Bad. Rumor further has it that such + systems really ought to be using -2 for "nobody", since that works. + So, if we get a uid (or gid, for good measure) of -1, switch to -2 + instead. Note that this must be done after we've looked up the + user/group names with getpwuid(-1) and/or getgrgid(-1). + */ + if (gid == (gid_t) -1) gid = (gid_t) -2; + if (uid == (uid_t) -1) uid = (uid_t) -2; + + errno = 0; + if (setgroups_needed_p (gid) && + setgroups (1, &gid) < 0) + sgs_errno = errno ? errno : -1; + + errno = 0; + if (setgid (gid) != 0) + gid_errno = errno ? errno : -1; + + errno = 0; + if (setuid (uid) != 0) + uid_errno = errno ? errno : -1; + + if (uid_errno == 0 && gid_errno == 0 && sgs_errno == 0) + { + static char buf [1024]; + sprintf (buf, "changed uid/gid to %.100s/%.100s (%ld/%ld).", + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???"), + (long) uid, (long) gid); + if (message_ret) + *message_ret = buf; + return 0; + } + else + { + char buf [1024]; + gid_t groups[1024]; + int n, size; + + if (sgs_errno) + { + sprintf (buf, "%s: couldn't setgroups to %.100s (%ld)", + blurb(), + (g && g->gr_name ? g->gr_name : "???"), + (long) gid); + if (sgs_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + { + errno = sgs_errno; + perror(buf); + } + + fprintf (stderr, "%s: effective group list: ", blurb()); + size = sizeof(groups) / sizeof(gid_t); + n = getgroups (size - 1, groups); + if (n < 0) + fprintf (stderr, "unknown!\n"); + else + { + int i; + fprintf (stderr, "["); + for (i = 0; i < n; i++) + { + g = getgrgid (groups[i]); + if (i > 0) fprintf (stderr, ", "); + if (g && g->gr_name) fprintf (stderr, "%s", g->gr_name); + else fprintf (stderr, "%ld", (long) groups[i]); + } + fprintf (stderr, "]\n"); + } + } + + if (gid_errno) + { + sprintf (buf, "%s: couldn't set gid to %.100s (%ld)", + blurb(), + (g && g->gr_name ? g->gr_name : "???"), + (long) gid); + if (gid_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + { + errno = gid_errno; + perror(buf); + } + } + + if (uid_errno) + { + sprintf (buf, "%s: couldn't set uid to %.100s (%ld)", + blurb(), + (p && p->pw_name ? p->pw_name : "???"), + (long) uid); + if (uid_errno == -1) + fprintf(stderr, "%s: unknown error\n", buf); + else + { + errno = uid_errno; + perror(buf); + } + } + + return -1; + } +} + + +/* If we've been run as setuid or setgid to someone else (most likely root) + turn off the extra permissions so that random user-specified programs + don't get special privileges. (On some systems it is necessary to install + this program as setuid root in order to read the passwd file to implement + lock-mode.) + + *** WARNING: DO NOT DISABLE ANY OF THE FOLLOWING CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ +void +hack_uid (saver_info *si) +{ + + /* Discard privileges, and set the effective user/group ids to the + real user/group ids. That is, give up our "chmod +s" rights. + */ + { + uid_t euid = geteuid(); + gid_t egid = getegid(); + uid_t uid = getuid(); + gid_t gid = getgid(); + + si->orig_uid = strdup (uid_gid_string (euid, egid)); + + if (uid != euid || gid != egid) + if (set_ids_by_number (uid, gid, &si->uid_message) != 0) + saver_exit (si, 1, 0); + } + + + /* Locking can't work when running as root, because we have no way of + knowing what the user id of the logged in user is (so we don't know + whose password to prompt for.) + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + if (getuid() == (uid_t) 0) + { + si->locking_disabled_p = True; + si->nolock_reason = "running as root"; + } + + + /* If we're running as root, switch to a safer user. This is above and + beyond the fact that we've disabling locking, above -- the theory is + that running graphics demos as root is just always a stupid thing + to do, since they have probably never been security reviewed and are + more likely to be buggy than just about any other kind of program. + (And that assumes non-malicious code. There are also attacks here.) + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + if (getuid() == (uid_t) 0) + { + struct passwd *p; + + p = getpwnam ("nobody"); + if (! p) p = getpwnam ("noaccess"); + if (! p) p = getpwnam ("daemon"); + if (! p) + { + fprintf (stderr, + "%s: running as root, and couldn't find a safer uid.\n", + blurb()); + saver_exit(si, 1, 0); + } + + if (set_ids_by_number (p->pw_uid, p->pw_gid, &si->uid_message) != 0) + saver_exit (si, -1, 0); + } + + + /* If there's anything even remotely funny looking about the passwd struct, + or if we're running as some other user from the list below (a + non-comprehensive selection of users known to be privileged in some way, + and not normal end-users) then disable locking. If it was possible, + switching to "nobody" would be the thing to do, but only root itself has + the privs to do that. + + *** WARNING: DO NOT DISABLE THIS CODE! + If you do so, you will open a security hole. See the sections + of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", + and "USING XDM". + */ + { + uid_t uid = getuid (); /* get it again */ + struct passwd *p = getpwuid (uid); /* get it again */ + + if (!p || + uid == (uid_t) 0 || + uid == (uid_t) -1 || + uid == (uid_t) -2 || + p->pw_uid == (uid_t) 0 || + p->pw_uid == (uid_t) -1 || + p->pw_uid == (uid_t) -2 || + !p->pw_name || + !*p->pw_name || + !strcmp (p->pw_name, "root") || + !strcmp (p->pw_name, "nobody") || + !strcmp (p->pw_name, "noaccess") || + !strcmp (p->pw_name, "operator") || + !strcmp (p->pw_name, "daemon") || + !strcmp (p->pw_name, "bin") || + !strcmp (p->pw_name, "adm") || + !strcmp (p->pw_name, "sys") || + !strcmp (p->pw_name, "games")) + { + static char buf [1024]; + sprintf (buf, "running as %.100s", + (p && p->pw_name && *p->pw_name + ? p->pw_name : "")); + si->nolock_reason = buf; + si->locking_disabled_p = True; + si->dangerous_uid_p = True; + } + } +} diff --git a/driver/splash.c b/driver/splash.c new file mode 100644 index 00000000..bc830029 --- /dev/null +++ b/driver/splash.c @@ -0,0 +1,925 @@ +/* xscreensaver, Copyright (c) 1991-2013 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "xscreensaver.h" +#include "resources.h" + +#undef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) + +void +draw_shaded_rectangle (Display *dpy, Window window, + int x, int y, + int width, int height, + int thickness, + unsigned long top_color, + unsigned long bottom_color) +{ + XPoint points[4]; + XGCValues gcv; + GC gc1, gc2; + if (thickness == 0) return; + + gcv.foreground = top_color; + gc1 = XCreateGC (dpy, window, GCForeground, &gcv); + gcv.foreground = bottom_color; + gc2 = XCreateGC (dpy, window, GCForeground, &gcv); + + points [0].x = x; + points [0].y = y; + points [1].x = x + width; + points [1].y = y; + points [2].x = x + width - thickness; + points [2].y = y + thickness; + points [3].x = x; + points [3].y = y + thickness; + XFillPolygon (dpy, window, gc1, points, 4, Convex, CoordModeOrigin); + + points [0].x = x; + points [0].y = y + thickness; + points [1].x = x; + points [1].y = y + height; + points [2].x = x + thickness; + points [2].y = y + height - thickness; + points [3].x = x + thickness; + points [3].y = y + thickness; + XFillPolygon (dpy, window, gc1, points, 4, Convex, CoordModeOrigin); + + points [0].x = x + width; + points [0].y = y; + points [1].x = x + width - thickness; + points [1].y = y + thickness; + points [2].x = x + width - thickness; + points [2].y = y + height - thickness; + points [3].x = x + width; + points [3].y = y + height - thickness; + XFillPolygon (dpy, window, gc2, points, 4, Convex, CoordModeOrigin); + + points [0].x = x; + points [0].y = y + height; + points [1].x = x + width; + points [1].y = y + height; + points [2].x = x + width; + points [2].y = y + height - thickness; + points [3].x = x + thickness; + points [3].y = y + height - thickness; + XFillPolygon (dpy, window, gc2, points, 4, Convex, CoordModeOrigin); + + XFreeGC (dpy, gc1); + XFreeGC (dpy, gc2); +} + + +int +string_width (XFontStruct *font, char *s) +{ + return XTextWidth(font, s, strlen(s)); +} + + +static void update_splash_window (saver_info *si); +static void draw_splash_window (saver_info *si); +static void destroy_splash_window (saver_info *si); +static void unsplash_timer (XtPointer closure, XtIntervalId *id); + +static void do_demo (saver_screen_info *ssi); +#ifdef PREFS_BUTTON +static void do_prefs (saver_screen_info *ssi); +#endif /* PREFS_BUTTON */ +static void do_help (saver_screen_info *ssi); + + +struct splash_dialog_data { + + saver_screen_info *prompt_screen; + XtIntervalId timer; + + Dimension width; + Dimension height; + + char *heading_label; + char *body_label; + char *body2_label; + char *body3_label; + char *body4_label; + char *demo_label; +#ifdef PREFS_BUTTON + char *prefs_label; +#endif /* PREFS_BUTTON */ + char *help_label; + + XFontStruct *heading_font; + XFontStruct *body_font; + XFontStruct *button_font; + + Pixel foreground; + Pixel background; + Pixel border; + Pixel button_foreground; + Pixel button_background; + Pixel shadow_top; + Pixel shadow_bottom; + + Dimension logo_width; + Dimension logo_height; + Dimension internal_border; + Dimension shadow_width; + + Dimension button_width, button_height; + Dimension demo_button_x, demo_button_y; +#ifdef PREFS_BUTTON + Dimension prefs_button_x, prefs_button_y; +#endif /* PREFS_BUTTON */ + Dimension help_button_x, help_button_y; + + Pixmap logo_pixmap; + Pixmap logo_clipmask; + int logo_npixels; + unsigned long *logo_pixels; + + int pressed; +}; + + +void +make_splash_dialog (saver_info *si) +{ + saver_preferences *p = &si->prefs; + int x, y, bw; + XSetWindowAttributes attrs; + unsigned long attrmask = 0; + splash_dialog_data *sp; + saver_screen_info *ssi; + Colormap cmap; + char *f; + + Bool whine = senescent_p (); + + if (whine) + { + /* If locking is not enabled, make sure they see the message. */ + if (!p->lock_p) + { + si->prefs.splash_p = True; + if (si->prefs.splash_duration < 5000) + si->prefs.splash_duration = 5000; + } + si->prefs.splash_duration += 3000; + } + + if (si->sp_data) + return; + if (!si->prefs.splash_p || + si->prefs.splash_duration <= 0) + return; + + ssi = &si->screens[mouse_screen (si)]; + + if (!ssi || !ssi->screen) + return; /* WTF? Trying to splash while no screens connected? */ + + cmap = DefaultColormapOfScreen (ssi->screen); + + sp = (splash_dialog_data *) calloc (1, sizeof(*sp)); + sp->prompt_screen = ssi; + + sp->heading_label = get_string_resource (si->dpy, + "splash.heading.label", + "Dialog.Label.Label"); + sp->body_label = get_string_resource (si->dpy, + "splash.body.label", + "Dialog.Label.Label"); + sp->body2_label = get_string_resource (si->dpy, + "splash.body2.label", + "Dialog.Label.Label"); + sp->demo_label = get_string_resource (si->dpy, + "splash.demo.label", + "Dialog.Button.Label"); +#ifdef PREFS_BUTTON + sp->prefs_label = get_string_resource (si->dpy, + "splash.prefs.label", + "Dialog.Button.Label"); +#endif /* PREFS_BUTTON */ + sp->help_label = get_string_resource (si->dpy, + "splash.help.label", + "Dialog.Button.Label"); + + + + if (whine) + { + sp->body3_label = strdup("WARNING: This version is very old!"); + sp->body4_label = strdup("Please upgrade!"); + } + + if (!sp->heading_label) + sp->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!sp->body_label) + sp->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!sp->body2_label) + sp->body2_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY"); + if (!sp->demo_label) sp->demo_label = strdup("ERROR"); +#ifdef PREFS_BUTTON + if (!sp->prefs_label) sp->prefs_label = strdup("ERROR"); +#endif /* PREFS_BUTTON */ + if (!sp->help_label) sp->help_label = strdup("ERROR"); + + /* Put the version number in the label. */ + { + char *s = (char *) malloc (strlen(sp->heading_label) + 20); + sprintf(s, sp->heading_label, si->version); + free (sp->heading_label); + sp->heading_label = s; + } + + 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(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(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 (si->dpy, cmap, + "splash.foreground", + "Dialog.Foreground"); + sp->background = get_pixel_resource (si->dpy, cmap, + "splash.background", + "Dialog.Background"); + sp->border = get_pixel_resource (si->dpy, cmap, + "splash.borderColor", + "Dialog.borderColor"); + + if (sp->foreground == sp->background) + { + /* Make sure the error messages show up. */ + sp->foreground = BlackPixelOfScreen (ssi->screen); + sp->background = WhitePixelOfScreen (ssi->screen); + } + + 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 (si->dpy, + "splash.logo.height", + "Dialog.Logo.Height"); + sp->internal_border = get_integer_resource (si->dpy, + "splash.internalBorderWidth", + "Dialog.InternalBorderWidth"); + sp->shadow_width = get_integer_resource (si->dpy, + "splash.shadowThickness", + "Dialog.ShadowThickness"); + + if (sp->logo_width == 0) sp->logo_width = 150; + if (sp->logo_height == 0) sp->logo_height = 150; + if (sp->internal_border == 0) sp->internal_border = 15; + if (sp->shadow_width == 0) sp->shadow_width = 4; + + { + int direction, ascent, descent; + XCharStruct overall; + + sp->width = 0; + sp->height = 0; + + /* Measure the heading_label. */ + XTextExtents (sp->heading_font, + sp->heading_label, strlen(sp->heading_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += ascent + descent; + + /* Measure the body_label. */ + XTextExtents (sp->body_font, + sp->body_label, strlen(sp->body_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += ascent + descent; + + /* Measure the body2_label. */ + XTextExtents (sp->body_font, + sp->body2_label, strlen(sp->body2_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += ascent + descent; + + /* Measure the optional body3_label. */ + if (sp->body3_label) + { + XTextExtents (sp->heading_font, + sp->body3_label, strlen(sp->body3_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + XTextExtents (sp->heading_font, + sp->body4_label, strlen(sp->body4_label), + &direction, &ascent, &descent, &overall); + if (overall.width > sp->width) sp->width = overall.width; + sp->height += (ascent + descent) * 5; + } + + { + Dimension w2 = 0, w3 = 0, w4 = 0; + Dimension h2 = 0, h3 = 0, h4 = 0; + + /* Measure the Demo button. */ + XTextExtents (sp->button_font, + sp->demo_label, strlen(sp->demo_label), + &direction, &ascent, &descent, &overall); + w2 = overall.width; + h2 = ascent + descent; + +#ifdef PREFS_BUTTON + /* Measure the Prefs button. */ + XTextExtents (sp->button_font, + sp->prefs_label, strlen(sp->prefs_label), + &direction, &ascent, &descent, &overall); + w3 = overall.width; + h3 = ascent + descent; +#else /* !PREFS_BUTTON */ + w3 = 0; + h3 = 0; +#endif /* !PREFS_BUTTON */ + + /* Measure the Help button. */ + XTextExtents (sp->button_font, + sp->help_label, strlen(sp->help_label), + &direction, &ascent, &descent, &overall); + w4 = overall.width; + h4 = ascent + descent; + + w2 = MAX(w2, w3); w2 = MAX(w2, w4); + h2 = MAX(h2, h3); h2 = MAX(h2, h4); + + /* Add some horizontal padding inside the buttons. */ + w2 += ascent; + + w2 += ((ascent + descent) / 2) + (sp->shadow_width * 2); + h2 += ((ascent + descent) / 2) + (sp->shadow_width * 2); + + sp->button_width = w2; + sp->button_height = h2; + +#ifdef PREFS_BUTTON + w2 *= 3; +#else /* !PREFS_BUTTON */ + w2 *= 2; +#endif /* !PREFS_BUTTON */ + + w2 += ((ascent + descent) * 2); /* for space between buttons */ + + if (w2 > sp->width) sp->width = w2; + sp->height += h2; + } + + sp->width += (sp->internal_border * 2); + sp->height += (sp->internal_border * 3); + + if (sp->logo_height > sp->height) + sp->height = sp->logo_height; + else if (sp->height > sp->logo_height) + sp->logo_height = sp->height; + + sp->logo_width = sp->logo_height; + + sp->width += sp->logo_width; + } + + attrmask |= CWOverrideRedirect; attrs.override_redirect = True; + attrmask |= CWEventMask; + attrs.event_mask = (ExposureMask | ButtonPressMask | ButtonReleaseMask); + + { + int sx = 0, sy = 0, w, h; + int mouse_x = 0, mouse_y = 0; + + { + Window pointer_root, pointer_child; + int root_x, root_y, win_x, win_y; + unsigned int mask; + if (XQueryPointer (si->dpy, + RootWindowOfScreen (ssi->screen), + &pointer_root, &pointer_child, + &root_x, &root_y, &win_x, &win_y, &mask)) + { + mouse_x = root_x; + mouse_y = root_y; + } + } + + x = ssi->x; + y = ssi->y; + w = ssi->width; + h = ssi->height; + if (si->prefs.debug_p) w /= 2; + x = sx + (((w + sp->width) / 2) - sp->width); + y = sy + (((h + sp->height) / 2) - sp->height); + if (x < sx) x = sx; + if (y < sy) y = sy; + } + + bw = get_integer_resource (si->dpy, + "splash.borderWidth", + "Dialog.BorderWidth"); + + si->splash_dialog = + XCreateWindow (si->dpy, + RootWindowOfScreen(ssi->screen), + x, y, sp->width, sp->height, bw, + DefaultDepthOfScreen (ssi->screen), InputOutput, + DefaultVisualOfScreen(ssi->screen), + attrmask, &attrs); + XSetWindowBackground (si->dpy, si->splash_dialog, sp->background); + XSetWindowBorder (si->dpy, si->splash_dialog, sp->border); + + + sp->logo_pixmap = xscreensaver_logo (ssi->screen, + /* same visual as si->splash_dialog */ + DefaultVisualOfScreen (ssi->screen), + si->splash_dialog, cmap, + sp->background, + &sp->logo_pixels, &sp->logo_npixels, + &sp->logo_clipmask, True); + + XMapRaised (si->dpy, si->splash_dialog); + XSync (si->dpy, False); + + si->sp_data = sp; + + sp->timer = XtAppAddTimeOut (si->app, si->prefs.splash_duration, + unsplash_timer, (XtPointer) si); + + draw_splash_window (si); + XSync (si->dpy, False); +} + + +static void +draw_splash_window (saver_info *si) +{ + splash_dialog_data *sp = si->sp_data; + XGCValues gcv; + GC gc1, gc2; + int hspacing, vspacing, height; + int x1, x2, x3, y1, y2; + int sw; + +#ifdef PREFS_BUTTON + int nbuttons = 3; +#else /* !PREFS_BUTTON */ + int nbuttons = 2; +#endif /* !PREFS_BUTTON */ + + height = (sp->heading_font->ascent + sp->heading_font->descent + + sp->body_font->ascent + sp->body_font->descent + + sp->body_font->ascent + sp->body_font->descent + + sp->button_font->ascent + sp->button_font->descent); + vspacing = ((sp->height + - (4 * sp->shadow_width) + - (2 * sp->internal_border) + - height) / 5); + if (vspacing < 0) vspacing = 0; + if (vspacing > (sp->heading_font->ascent * 2)) + vspacing = (sp->heading_font->ascent * 2); + + gcv.foreground = sp->foreground; + gc1 = XCreateGC (si->dpy, si->splash_dialog, GCForeground, &gcv); + gc2 = XCreateGC (si->dpy, si->splash_dialog, GCForeground, &gcv); + x1 = sp->logo_width; + x3 = sp->width - (sp->shadow_width * 2); + y1 = sp->internal_border; + + /* top heading + */ + XSetFont (si->dpy, gc1, sp->heading_font->fid); + sw = string_width (sp->heading_font, sp->heading_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + y1 += sp->heading_font->ascent; + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->heading_label, strlen(sp->heading_label)); + y1 += sp->heading_font->descent; + + /* text below top heading + */ + XSetFont (si->dpy, gc1, sp->body_font->fid); + y1 += vspacing + sp->body_font->ascent; + sw = string_width (sp->body_font, sp->body_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->body_label, strlen(sp->body_label)); + y1 += sp->body_font->descent; + + y1 += sp->body_font->ascent; + sw = string_width (sp->body_font, sp->body2_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->body2_label, strlen(sp->body2_label)); + y1 += sp->body_font->descent; + + if (sp->body3_label) + { + XSetFont (si->dpy, gc1, sp->heading_font->fid); + y1 += sp->heading_font->ascent + sp->heading_font->descent; + y1 += sp->heading_font->ascent; + sw = string_width (sp->heading_font, sp->body3_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->body3_label, strlen(sp->body3_label)); + y1 += sp->heading_font->descent + sp->heading_font->ascent; + sw = string_width (sp->heading_font, sp->body4_label); + x2 = (x1 + ((x3 - x1 - sw) / 2)); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y1, + sp->body4_label, strlen(sp->body4_label)); + y1 += sp->heading_font->descent; + XSetFont (si->dpy, gc1, sp->body_font->fid); + } + + /* The buttons + */ + XSetForeground (si->dpy, gc1, sp->button_foreground); + XSetForeground (si->dpy, gc2, sp->button_background); + +/* y1 += (vspacing * 2);*/ + y1 = sp->height - sp->internal_border - sp->button_height; + + x1 += sp->internal_border; + y2 = (y1 + ((sp->button_height - + (sp->button_font->ascent + sp->button_font->descent)) + / 2) + + sp->button_font->ascent); + hspacing = ((sp->width - x1 - (sp->shadow_width * 2) - + sp->internal_border - (sp->button_width * nbuttons)) + / 2); + + x2 = x1 + ((sp->button_width - string_width(sp->button_font, sp->demo_label)) + / 2); + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, + sp->button_width, sp->button_height); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y2, + sp->demo_label, strlen(sp->demo_label)); + sp->demo_button_x = x1; + sp->demo_button_y = y1; + +#ifdef PREFS_BUTTON + x1 += hspacing + sp->button_width; + x2 = x1 + ((sp->button_width - string_width(sp->button_font,sp->prefs_label)) + / 2); + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, + sp->button_width, sp->button_height); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y2, + sp->prefs_label, strlen(sp->prefs_label)); + sp->prefs_button_x = x1; + sp->prefs_button_y = y1; +#endif /* PREFS_BUTTON */ + +#ifdef PREFS_BUTTON + x1 += hspacing + sp->button_width; +#else /* !PREFS_BUTTON */ + x1 = (sp->width - sp->button_width - + sp->internal_border - (sp->shadow_width * 2)); +#endif /* !PREFS_BUTTON */ + + x2 = x1 + ((sp->button_width - string_width(sp->button_font,sp->help_label)) + / 2); + XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, + sp->button_width, sp->button_height); + XDrawString (si->dpy, si->splash_dialog, gc1, x2, y2, + sp->help_label, strlen(sp->help_label)); + sp->help_button_x = x1; + sp->help_button_y = y1; + + + /* The logo + */ + x1 = sp->shadow_width * 6; + y1 = sp->shadow_width * 6; + x2 = sp->logo_width - (sp->shadow_width * 12); + y2 = sp->logo_height - (sp->shadow_width * 12); + + if (sp->logo_pixmap) + { + Window root; + int x, y; + unsigned int w, h, bw, d; + 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, + x1 + ((x2 - (int)w) / 2), + y1 + ((y2 - (int)h) / 2), + 1); + else + XCopyArea (si->dpy, sp->logo_pixmap, si->splash_dialog, gc1, + 0, 0, w, h, + x1 + ((x2 - (int)w) / 2), + y1 + ((y2 - (int)h) / 2)); + } + + /* Solid border inside the logo box. */ +#if 0 + XSetForeground (si->dpy, gc1, sp->foreground); + XDrawRectangle (si->dpy, si->splash_dialog, gc1, x1, y1, x2-1, y2-1); +#endif + + /* The shadow around the logo + */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->shadow_width * 4, + sp->shadow_width * 4, + sp->logo_width - (sp->shadow_width * 8), + sp->logo_height - (sp->shadow_width * 8), + sp->shadow_width, + sp->shadow_bottom, sp->shadow_top); + + /* The shadow around the whole window + */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + 0, 0, sp->width, sp->height, sp->shadow_width, + sp->shadow_top, sp->shadow_bottom); + + XFreeGC (si->dpy, gc1); + XFreeGC (si->dpy, gc2); + + update_splash_window (si); +} + + +static void +update_splash_window (saver_info *si) +{ + splash_dialog_data *sp = si->sp_data; + int pressed; + if (!sp) return; + pressed = sp->pressed; + + /* The shadows around the buttons + */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->demo_button_x, sp->demo_button_y, + sp->button_width, sp->button_height, sp->shadow_width, + (pressed == 1 ? sp->shadow_bottom : sp->shadow_top), + (pressed == 1 ? sp->shadow_top : sp->shadow_bottom)); +#ifdef PREFS_BUTTON + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->prefs_button_x, sp->prefs_button_y, + sp->button_width, sp->button_height, sp->shadow_width, + (pressed == 2 ? sp->shadow_bottom : sp->shadow_top), + (pressed == 2 ? sp->shadow_top : sp->shadow_bottom)); +#endif /* PREFS_BUTTON */ + draw_shaded_rectangle (si->dpy, si->splash_dialog, + sp->help_button_x, sp->help_button_y, + sp->button_width, sp->button_height, sp->shadow_width, + (pressed == 3 ? sp->shadow_bottom : sp->shadow_top), + (pressed == 3 ? sp->shadow_top : sp->shadow_bottom)); +} + +static void +destroy_splash_window (saver_info *si) +{ + splash_dialog_data *sp = si->sp_data; + saver_screen_info *ssi = sp->prompt_screen; + Colormap cmap = DefaultColormapOfScreen (ssi->screen); + Pixel black = BlackPixelOfScreen (ssi->screen); + Pixel white = WhitePixelOfScreen (ssi->screen); + + if (sp->timer) + XtRemoveTimeOut (sp->timer); + + if (si->splash_dialog) + { + XDestroyWindow (si->dpy, si->splash_dialog); + si->splash_dialog = 0; + } + + if (sp->heading_label) free (sp->heading_label); + if (sp->body_label) free (sp->body_label); + if (sp->body2_label) free (sp->body2_label); + if (sp->body3_label) free (sp->body3_label); + if (sp->body4_label) free (sp->body4_label); + if (sp->demo_label) free (sp->demo_label); +#ifdef PREFS_BUTTON + if (sp->prefs_label) free (sp->prefs_label); +#endif /* PREFS_BUTTON */ + if (sp->help_label) free (sp->help_label); + + if (sp->heading_font) XFreeFont (si->dpy, sp->heading_font); + if (sp->body_font) XFreeFont (si->dpy, sp->body_font); + if (sp->button_font) XFreeFont (si->dpy, sp->button_font); + + if (sp->foreground != black && sp->foreground != white) + XFreeColors (si->dpy, cmap, &sp->foreground, 1, 0L); + if (sp->background != black && sp->background != white) + XFreeColors (si->dpy, cmap, &sp->background, 1, 0L); + if (sp->button_foreground != black && sp->button_foreground != white) + XFreeColors (si->dpy, cmap, &sp->button_foreground, 1, 0L); + if (sp->button_background != black && sp->button_background != white) + XFreeColors (si->dpy, cmap, &sp->button_background, 1, 0L); + if (sp->shadow_top != black && sp->shadow_top != white) + XFreeColors (si->dpy, cmap, &sp->shadow_top, 1, 0L); + if (sp->shadow_bottom != black && sp->shadow_bottom != white) + XFreeColors (si->dpy, cmap, &sp->shadow_bottom, 1, 0L); + + 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) + XFreeColors (si->dpy, cmap, sp->logo_pixels, sp->logo_npixels, 0L); + free (sp->logo_pixels); + sp->logo_pixels = 0; + sp->logo_npixels = 0; + } + + memset (sp, 0, sizeof(*sp)); + free (sp); + si->sp_data = 0; +} + +void +handle_splash_event (saver_info *si, XEvent *event) +{ + splash_dialog_data *sp = si->sp_data; + saver_screen_info *ssi = sp->prompt_screen; + int which = 0; + if (!sp) return; + + switch (event->xany.type) + { + case Expose: + draw_splash_window (si); + break; + + case ButtonPress: case ButtonRelease: + + if (event->xbutton.x >= sp->demo_button_x && + event->xbutton.x < sp->demo_button_x + sp->button_width && + event->xbutton.y >= sp->demo_button_y && + event->xbutton.y < sp->demo_button_y + sp->button_height) + which = 1; + +#ifdef PREFS_BUTTON + else if (event->xbutton.x >= sp->prefs_button_x && + event->xbutton.x < sp->prefs_button_x + sp->button_width && + event->xbutton.y >= sp->prefs_button_y && + event->xbutton.y < sp->prefs_button_y + sp->button_height) + which = 2; +#endif /* PREFS_BUTTON */ + + else if (event->xbutton.x >= sp->help_button_x && + event->xbutton.x < sp->help_button_x + sp->button_width && + event->xbutton.y >= sp->help_button_y && + event->xbutton.y < sp->help_button_y + sp->button_height) + which = 3; + + if (event->xany.type == ButtonPress) + { + sp->pressed = which; + update_splash_window (si); + if (which == 0) + XBell (si->dpy, False); + } + else if (event->xany.type == ButtonRelease) + { + if (which && sp->pressed == which) + { + destroy_splash_window (si); + sp = si->sp_data; + switch (which) + { + case 1: do_demo (ssi); break; +#ifdef PREFS_BUTTON + case 2: do_prefs (ssi); break; +#endif /* PREFS_BUTTON */ + case 3: do_help (ssi); break; + default: abort(); + } + } + else if (which == 0 && sp->pressed == 0) + { + /* click and release on the window but not in a button: + treat that as "dismiss the splash dialog." */ + destroy_splash_window (si); + sp = si->sp_data; + } + if (sp) sp->pressed = 0; + update_splash_window (si); + } + break; + + default: + break; + } +} + +static void +unsplash_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + if (si && si->sp_data) + destroy_splash_window (si); +} + + +/* Button callbacks */ + +#ifdef VMS +# define pid_t int +# define fork vfork +#endif /* VMS */ + + +static void +do_demo (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + const char *cmd = p->demo_command; + + if (cmd && *cmd) + fork_and_exec (ssi, cmd); + else + fprintf (stderr, "%s: no demo-mode command has been specified.\n", + blurb()); +} + +#ifdef PREFS_BUTTON +static void +do_prefs (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + const char *cmd = p->prefs_command; + + if (command && *command) + fork_and_exec (ssi, cmd); + else + fprintf (stderr, "%s: no preferences command has been specified.\n", + blurb()); +} +#endif /* PREFS_BUTTON */ + +static void +do_help (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + char *help_command = 0; + + if (!p->load_url_command || !*p->load_url_command) + { + fprintf (stderr, "%s: no URL command has been specified.\n", blurb()); + return; + } + if (!p->help_url || !*p->help_url) + { + fprintf (stderr, "%s: no Help URL has been specified.\n", blurb()); + return; + } + + help_command = (char *) malloc (strlen (p->load_url_command) + + (strlen (p->help_url) * 4) + 10); + sprintf (help_command, p->load_url_command, + p->help_url, p->help_url, p->help_url, p->help_url); + + fork_and_exec (ssi, help_command); + free (help_command); +} diff --git a/driver/stderr.c b/driver/stderr.c new file mode 100644 index 00000000..7def5d92 --- /dev/null +++ b/driver/stderr.c @@ -0,0 +1,560 @@ +/* stderr.c --- capturing stdout/stderr output onto the screensaver window. + * xscreensaver, Copyright (c) 1991-2012 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. + */ + +/* stderr hackery - Why Unix Sucks, reason number 32767. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_FCNTL +# include +#endif + +#include + +#include "xscreensaver.h" +#include "resources.h" +#include "visual.h" + +FILE *real_stderr = 0; +FILE *real_stdout = 0; + + +/* It's ok for these to be global, since they refer to the one and only + stderr stream, not to a particular screen or window or visual. + */ +static char stderr_buffer [4096]; +static char *stderr_tail = 0; +static time_t stderr_last_read = 0; + +static int stderr_stdout_read_fd = -1; + +static void make_stderr_overlay_window (saver_screen_info *); + + +/* Recreates the stderr window or GCs: do this when the xscreensaver window + on a screen has been re-created. + */ +void +reset_stderr (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + + if (si->prefs.debug_p) + fprintf ((real_stderr ? real_stderr : stderr), + "%s: resetting stderr\n", blurb()); + + ssi->stderr_text_x = 0; + ssi->stderr_text_y = 0; + + if (ssi->stderr_gc) + XFreeGC (si->dpy, ssi->stderr_gc); + ssi->stderr_gc = 0; + + if (ssi->stderr_overlay_window) + XDestroyWindow(si->dpy, ssi->stderr_overlay_window); + ssi->stderr_overlay_window = 0; + + if (ssi->stderr_cmap) + XFreeColormap(si->dpy, ssi->stderr_cmap); + ssi->stderr_cmap = 0; +} + +/* Erases any stderr text overlaying the screen (if possible) and resets + the stderr output cursor to the upper left. Do this when the xscreensaver + window is cleared. + */ +void +clear_stderr (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + ssi->stderr_text_x = 0; + ssi->stderr_text_y = 0; + if (ssi->stderr_overlay_window) + XClearWindow (si->dpy, ssi->stderr_overlay_window); +} + + +/* Draws the string on the screen's window. + */ +static void +print_stderr_1 (saver_screen_info *ssi, char *string) +{ + saver_info *si = ssi->global; + Display *dpy = si->dpy; + Screen *screen = ssi->screen; + Window window = (ssi->stderr_overlay_window ? + ssi->stderr_overlay_window : + ssi->screensaver_window); + int h_border = 20; + int v_border = 20; + char *head = string; + char *tail; + + if (! ssi->stderr_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"); + ssi->stderr_line_height = (ssi->stderr_font->ascent + + ssi->stderr_font->descent); + free (font_name); + } + + if (! ssi->stderr_gc) + { + XGCValues gcv; + Pixel fg, bg; + Colormap cmap = ssi->cmap; + + if (!ssi->stderr_overlay_window && + get_boolean_resource(dpy, "overlayStderr", "Boolean")) + { + make_stderr_overlay_window (ssi); + if (ssi->stderr_overlay_window) + window = ssi->stderr_overlay_window; + if (ssi->stderr_cmap) + cmap = ssi->stderr_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; + ssi->stderr_gc = XCreateGC (dpy, window, + (GCFont | GCForeground | GCBackground), + &gcv); + } + + + if (ssi->stderr_cmap) + XInstallColormap(si->dpy, ssi->stderr_cmap); + + for (tail = string; *tail; tail++) + { + if (*tail == '\n' || *tail == '\r') + { + int maxy = HeightOfScreen (screen) - v_border - v_border; + if (tail != head) + XDrawImageString (dpy, window, ssi->stderr_gc, + ssi->stderr_text_x + h_border, + ssi->stderr_text_y + v_border + + ssi->stderr_font->ascent, + head, tail - head); + ssi->stderr_text_x = 0; + ssi->stderr_text_y += ssi->stderr_line_height; + head = tail + 1; + if (*tail == '\r' && *head == '\n') + head++, tail++; + + if (ssi->stderr_text_y > maxy - ssi->stderr_line_height) + { +#if 0 + ssi->stderr_text_y = 0; +#else + int offset = ssi->stderr_line_height * 5; + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + + XCopyArea (dpy, window, window, ssi->stderr_gc, + 0, v_border + offset, + xgwa.width, + (xgwa.height - v_border - v_border - offset), + 0, v_border); + XClearArea (dpy, window, + 0, xgwa.height - v_border - offset, + xgwa.width, offset, False); + ssi->stderr_text_y -= offset; +#endif + } + } + } + if (tail != head) + { + int direction, ascent, descent; + XCharStruct overall; + XDrawImageString (dpy, window, ssi->stderr_gc, + ssi->stderr_text_x + h_border, + ssi->stderr_text_y + v_border + + ssi->stderr_font->ascent, + head, tail - head); + XTextExtents (ssi->stderr_font, tail, tail - head, + &direction, &ascent, &descent, &overall); + ssi->stderr_text_x += overall.width; + } +} + +static void +make_stderr_overlay_window (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + unsigned long transparent_pixel = 0; + Visual *visual = get_overlay_visual (ssi->screen, &transparent_pixel); + if (visual) + { + int depth = visual_depth (ssi->screen, visual); + XSetWindowAttributes attrs; + XWindowAttributes xgwa; + unsigned long attrmask; + XGetWindowAttributes (si->dpy, ssi->screensaver_window, &xgwa); + + if (si->prefs.debug_p) + fprintf(real_stderr, + "%s: using overlay visual 0x%0x for stderr text layer.\n", + blurb(), (int) XVisualIDFromVisual (visual)); + + ssi->stderr_cmap = XCreateColormap(si->dpy, + RootWindowOfScreen(ssi->screen), + visual, AllocNone); + + attrmask = (CWColormap | CWBackPixel | CWBackingPixel | CWBorderPixel | + CWBackingStore | CWSaveUnder); + attrs.colormap = ssi->stderr_cmap; + attrs.background_pixel = transparent_pixel; + attrs.backing_pixel = transparent_pixel; + attrs.border_pixel = transparent_pixel; + attrs.backing_store = NotUseful; + attrs.save_under = False; + + ssi->stderr_overlay_window = + XCreateWindow(si->dpy, ssi->screensaver_window, 0, 0, + xgwa.width, xgwa.height, + 0, depth, InputOutput, visual, attrmask, &attrs); + XMapRaised(si->dpy, ssi->stderr_overlay_window); + } +} + + +/* Draws the string on each screen's window as error text. + */ +static void +print_stderr (saver_info *si, char *string) +{ + saver_preferences *p = &si->prefs; + int i; + + /* In verbose mode, copy it to stderr as well. */ + if (p->verbose_p) + fprintf (real_stderr, "%s", string); + + for (i = 0; i < si->nscreens; i++) + print_stderr_1 (&si->screens[i], string); +} + + +/* Polls the stderr buffer every few seconds and if it finds any text, + writes it on all screens. + */ +static void +stderr_popup_timer_fn (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + char *s = stderr_buffer; + if (*s) + { + /* If too much data was printed, then something has gone haywire, + so truncate it. */ + char *trailer = "\n\n<< stderr diagnostics have been truncated >>\n\n"; + int max = sizeof (stderr_buffer) - strlen (trailer) - 5; + if (strlen (s) > max) + strcpy (s + max, trailer); + /* Now show the user. */ + print_stderr (si, s); + } + + stderr_tail = stderr_buffer; + si->stderr_popup_timer = 0; +} + + +/* Called when data becomes available on the stderr pipe. Copies it into + stderr_buffer where stderr_popup_timer_fn() can find it later. + */ +static void +stderr_callback (XtPointer closure, int *fd, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + char *s; + int left; + int size; + int read_this_time = 0; + + if (!fd || *fd < 0 || *fd != stderr_stdout_read_fd) + abort(); + + if (stderr_tail == 0) + stderr_tail = stderr_buffer; + + left = ((sizeof (stderr_buffer) - 2) - (stderr_tail - stderr_buffer)); + + s = stderr_tail; + *s = 0; + + /* Read as much data from the fd as we can, up to our buffer size. */ + if (left > 0) + { + while ((size = read (*fd, (void *) s, left)) > 0) + { + left -= size; + s += size; + read_this_time += size; + } + *s = 0; + } + else + { + char buf2 [1024]; + /* The buffer is full; flush the rest of it. */ + while (read (*fd, (void *) buf2, sizeof (buf2)) > 0) + ; + } + + stderr_tail = s; + stderr_last_read = time ((time_t *) 0); + + /* Now we have read some data that we would like to put up in a dialog + box. But more data may still be coming in - so don't pop up the + dialog right now, but instead, start a timer that will pop it up + a second from now. Should more data come in in the meantime, we + will be called again, and will reset that timer again. So the + dialog will only pop up when a second has elapsed with no new data + being written to stderr. + + However, if the buffer is full (meaning lots of data has been written) + then we don't reset the timer. + */ + if (read_this_time > 0) + { + if (si->stderr_popup_timer) + XtRemoveTimeOut (si->stderr_popup_timer); + + si->stderr_popup_timer = + XtAppAddTimeOut (si->app, 1 * 1000, stderr_popup_timer_fn, + (XtPointer) si); + } +} + +/* If stderr capturing is desired, this replaces `stdout' and `stderr' + with a pipe, so that any output written to them will show up on the + screen as well as on the original value of those streams. + */ +void +initialize_stderr (saver_info *si) +{ + static Boolean done = False; + int fds [2]; + int in, out; + int new_stdout, new_stderr; + int stdout_fd = 1; + int stderr_fd = 2; + int flags = 0; + Boolean stderr_dialog_p; + + if (done) return; + done = True; + + real_stderr = stderr; + real_stdout = stdout; + + stderr_dialog_p = get_boolean_resource (si->dpy, "captureStderr", "Boolean"); + + if (!stderr_dialog_p) + return; + + if (pipe (fds)) + { + perror ("error creating pipe:"); + return; + } + + in = fds [0]; + out = fds [1]; + +# ifdef HAVE_FCNTL + +# if defined(O_NONBLOCK) + flags = O_NONBLOCK; +# elif defined(O_NDELAY) + flags = O_NDELAY; +# else + ERROR!! neither O_NONBLOCK nor O_NDELAY are defined. +# endif + + /* Set both sides of the pipe to nonblocking - this is so that + our reads (in stderr_callback) will terminate, and so that + out writes (in the client programs) will silently fail when + the pipe is full, instead of hosing the program. */ + if (fcntl (in, F_SETFL, flags) != 0) + { + perror ("fcntl:"); + return; + } + if (fcntl (out, F_SETFL, flags) != 0) + { + perror ("fcntl:"); + return; + } + +# endif /* !HAVE_FCNTL */ + + if (stderr_dialog_p) + { + FILE *new_stderr_file; + FILE *new_stdout_file; + + new_stderr = dup (stderr_fd); + if (new_stderr < 0) + { + perror ("could not dup() a stderr:"); + return; + } + if (! (new_stderr_file = fdopen (new_stderr, "w"))) + { + perror ("could not fdopen() the new stderr:"); + return; + } + real_stderr = new_stderr_file; + + close (stderr_fd); + if (dup2 (out, stderr_fd) < 0) + { + perror ("could not dup() a new stderr:"); + return; + } + + + new_stdout = dup (stdout_fd); + if (new_stdout < 0) + { + perror ("could not dup() a stdout:"); + return; + } + if (! (new_stdout_file = fdopen (new_stdout, "w"))) + { + perror ("could not fdopen() the new stdout:"); + return; + } + real_stdout = new_stdout_file; + + close (stdout_fd); + if (dup2 (out, stdout_fd) < 0) + { + perror ("could not dup() a new stdout:"); + return; + } + close (out); + } + + stderr_stdout_read_fd = in; + XtAppAddInput (si->app, in, (XtPointer) XtInputReadMask, stderr_callback, + (XtPointer) si); +} + + +/* If the "-log file" command-line option has been specified, + open the file for append, and redirect stdout/stderr there. + This is called very early, before initialize_stderr(). + */ +void +stderr_log_file (saver_info *si) +{ + int stdout_fd = 1; + int stderr_fd = 2; + const char *filename = get_string_resource (si->dpy, "logFile", "LogFile"); + int fd; + + if (!filename || !*filename) return; + + fd = open (filename, O_WRONLY | O_APPEND | O_CREAT, 0666); + + if (fd < 0) + { + char buf[255]; + FAIL: + sprintf (buf, "%.100s: %.100s", blurb(), filename); + perror (buf); + fflush (stderr); + fflush (stdout); + exit (1); + } + + fprintf (stderr, "%s: logging to file %s\n", blurb(), filename); + + if (dup2 (fd, stdout_fd) < 0) goto FAIL; + if (dup2 (fd, stderr_fd) < 0) goto FAIL; + + fprintf (stderr, "\n\n" + "##########################################################################\n" + "%s: logging to \"%s\" at %s\n" + "##########################################################################\n" + "\n", + blurb(), filename, timestring()); +} + + +/* If there is anything in the stderr buffer, flush it to the real stderr. + This does no X operations. Call this when exiting to make sure any + last words actually show up. + */ +void +shutdown_stderr (saver_info *si) +{ + fflush (stdout); + fflush (stderr); + + if (!real_stderr || stderr_stdout_read_fd < 0) + return; + + stderr_callback ((XtPointer) si, &stderr_stdout_read_fd, 0); + + if (stderr_tail && + stderr_buffer < stderr_tail) + { + *stderr_tail = 0; + fprintf (real_stderr, "%s", stderr_buffer); + stderr_tail = stderr_buffer; + } + + if (real_stdout) fflush (real_stdout); + if (real_stderr) fflush (real_stderr); + + if (stdout != real_stdout) + { + dup2 (fileno(real_stdout), fileno(stdout)); + fclose (real_stdout); + real_stdout = stdout; + } + if (stderr != real_stderr) + { + dup2 (fileno(real_stderr), fileno(stderr)); + fclose (real_stderr); + real_stderr = stderr; + } + if (stderr_stdout_read_fd != -1) + { + close (stderr_stdout_read_fd); + stderr_stdout_read_fd = -1; + } +} diff --git a/driver/subprocs.c b/driver/subprocs.c new file mode 100644 index 00000000..2a8f163e --- /dev/null +++ b/driver/subprocs.c @@ -0,0 +1,1375 @@ +/* subprocs.c --- choosing, spawning, and killing screenhacks. + * xscreensaver, Copyright (c) 1991-2012 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include /* not used for much... */ + +#ifndef ESRCH +# include +#endif + +#include /* sys/resource.h needs this for timeval */ +#include /* for PATH_MAX */ + +#ifdef HAVE_SYS_WAIT_H +# include /* for waitpid() and associated macros */ +#endif + +#ifdef HAVE_SETRLIMIT +# include /* for setrlimit() and RLIMIT_AS */ +#endif + +#ifdef VMS +# include +# include /* for close */ +# include /* for getpid */ +# define pid_t int +# define fork vfork +#endif /* VMS */ + +#include /* for the signal names */ + +#if !defined(SIGCHLD) && defined(SIGCLD) +# define SIGCHLD SIGCLD +#endif + +#if 0 /* putenv() is declared in stdlib.h on modern linux systems. */ +#ifdef HAVE_PUTENV +extern int putenv (/* const char * */); /* getenv() is in stdlib.h... */ +#endif +#endif + +extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" +#include "exec.h" +#include "yarandom.h" +#include "visual.h" /* for id_to_visual() */ + +extern saver_info *global_si_kludge; /* I hate C so much... */ + + +/* Used when printing error/debugging messages from signal handlers. + */ +static const char * +no_malloc_number_to_string (long num) +{ + static char string[128] = ""; + int num_digits; + Bool negative_p = False; + + num_digits = 0; + + if (num == 0) + return "0"; + + if (num < 0) + { + negative_p = True; + num = -num; + } + + while ((num > 0) && (num_digits < sizeof(string) - 1)) + { + int digit; + digit = (int) num % 10; + num_digits++; + string[sizeof(string) - 1 - num_digits] = digit + '0'; + num /= 10; + } + + if (negative_p) + { + num_digits++; + string[sizeof(string) - 1 - num_digits] = '-'; + } + + return string + sizeof(string) - 1 - num_digits; +} + +/* Like write(), but runs strlen() on the arg to get the length. */ +static int +write_string (int fd, const char *str) +{ + return write (fd, str, strlen (str)); +} + +static int +write_long (int fd, long n) +{ + const char *str = no_malloc_number_to_string (n); + return write_string (fd, str); +} + + +/* RLIMIT_AS (called RLIMIT_VMEM on some systems) controls the maximum size + of a process's address space, i.e., the maximal brk(2) and mmap(2) values. + Setting this lets you put a cap on how much memory a process can allocate. + + Except the "and mmap()" part kinda makes this useless, since many GL + implementations end up using mmap() to pull the whole frame buffer into + memory (or something along those lines) making it appear processes are + using hundreds of megabytes when in fact they're using very little, and + we end up capping their mallocs prematurely. YAY! + */ +#if defined(RLIMIT_VMEM) && !defined(RLIMIT_AS) +# define RLIMIT_AS RLIMIT_VMEM +#endif + +static void +limit_subproc_memory (int address_space_limit, Bool verbose_p) +{ + +/* This has caused way more problems than it has solved... + Let's just completely ignore the "memoryLimit" option now. + */ +#undef HAVE_SETRLIMIT + +#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_AS) + struct rlimit r; + + if (address_space_limit < 10 * 1024) /* let's not be crazy */ + return; + + if (getrlimit (RLIMIT_AS, &r) != 0) + { + char buf [512]; + sprintf (buf, "%s: getrlimit(RLIMIT_AS) failed", blurb()); + perror (buf); + return; + } + + r.rlim_cur = address_space_limit; + + if (setrlimit (RLIMIT_AS, &r) != 0) + { + char buf [512]; + sprintf (buf, "%s: setrlimit(RLIMIT_AS, {%lu, %lu}) failed", + blurb(), r.rlim_cur, r.rlim_max); + perror (buf); + return; + } + + if (verbose_p) + { + int i = address_space_limit; + char buf[100]; + if (i >= (1<<30) && i == ((i >> 30) << 30)) + sprintf(buf, "%dG", i >> 30); + else if (i >= (1<<20) && i == ((i >> 20) << 20)) + sprintf(buf, "%dM", i >> 20); + else if (i >= (1<<10) && i == ((i >> 10) << 10)) + sprintf(buf, "%dK", i >> 10); + else + sprintf(buf, "%d bytes", i); + + fprintf (stderr, "%s: limited pid %lu address space to %s.\n", + blurb(), (unsigned long) getpid (), buf); + } + +#endif /* HAVE_SETRLIMIT && RLIMIT_AS */ +} + + +/* Management of child processes, and de-zombification. + */ + +enum job_status { + job_running, /* the process is still alive */ + job_stopped, /* we have sent it a STOP signal */ + job_killed, /* we have sent it a TERM signal */ + job_dead /* we have wait()ed for it, and it's dead -- this state only + occurs so that we can avoid calling free() from a signal + handler. Shortly after going into this state, the list + element will be removed. */ +}; + +struct screenhack_job { + char *name; + pid_t pid; + int screen; + enum job_status status; + struct screenhack_job *next; +}; + +static struct screenhack_job *jobs = 0; + +/* for debugging -- nothing calls this, but it's useful to invoke from gdb. + */ +void show_job_list (void); + +void +show_job_list (void) +{ + struct screenhack_job *job; + fprintf(stderr, "%s: job list:\n", blurb()); + for (job = jobs; job; job = job->next) + fprintf (stderr, " %5ld: %2d: (%s) %s\n", + (long) job->pid, + job->screen, + (job->status == job_running ? "running" : + job->status == job_stopped ? "stopped" : + job->status == job_killed ? " killed" : + job->status == job_dead ? " dead" : " ???"), + job->name); + fprintf (stderr, "\n"); +} + + +static void clean_job_list (void); + +static struct screenhack_job * +make_job (pid_t pid, int screen, const char *cmd) +{ + struct screenhack_job *job = (struct screenhack_job *) malloc (sizeof(*job)); + + static char name [1024]; + const char *in = cmd; + char *out = name; + int got_eq = 0; + int first = 1; + + clean_job_list(); + + AGAIN: + while (isspace(*in)) in++; /* skip whitespace */ + while (!isspace(*in) && *in != ':') { + if (*in == '=') got_eq = 1; + *out++ = *in++; /* snarf first token */ + } + + if (got_eq) /* if the first token was FOO=bar */ + { /* then get the next token instead. */ + got_eq = 0; + out = name; + first = 0; + goto AGAIN; + } + + while (isspace(*in)) in++; /* skip whitespace */ + *out = 0; + + job->name = strdup(name); + job->pid = pid; + job->screen = screen; + job->status = job_running; + job->next = jobs; + jobs = job; + + return jobs; +} + + +static void +free_job (struct screenhack_job *job) +{ + if (!job) + return; + else if (job == jobs) + jobs = jobs->next; + else + { + struct screenhack_job *job2, *prev; + for (prev = 0, job2 = jobs; + job2; + prev = job2, job2 = job2->next) + if (job2 == job) + { + prev->next = job->next; + break; + } + } + free(job->name); + free(job); +} + + +/* Cleans out dead jobs from the jobs list -- this must only be called + from the main thread, not from a signal handler. + */ +static void +clean_job_list (void) +{ + struct screenhack_job *job, *prev, *next; + for (prev = 0, job = jobs, next = (job ? job->next : 0); + job; + prev = job, job = next, next = (job ? job->next : 0)) + { + if (job->status == job_dead) + { + if (prev) + prev->next = next; + free_job (job); + job = prev; + } + } +} + + +static struct screenhack_job * +find_job (pid_t pid) +{ + struct screenhack_job *job; + for (job = jobs; job; job = job->next) + if (job->pid == pid) + return job; + return 0; +} + +static void await_dying_children (saver_info *si); +#ifndef VMS +static void describe_dead_child (saver_info *, pid_t, int wait_status); +#endif + + +/* Semaphore to temporarily turn the SIGCHLD handler into a no-op. + Don't alter this directly -- use block_sigchld() / unblock_sigchld(). + */ +static int block_sigchld_handler = 0; + + +#ifdef HAVE_SIGACTION + sigset_t +#else /* !HAVE_SIGACTION */ + int +#endif /* !HAVE_SIGACTION */ +block_sigchld (void) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa; + sigset_t child_set; + + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = SIG_IGN; + sigaction (SIGPIPE, &sa, NULL); + + sigemptyset (&child_set); + sigaddset (&child_set, SIGCHLD); + sigprocmask (SIG_BLOCK, &child_set, 0); + +#else /* !HAVE_SIGACTION */ + signal (SIGPIPE, SIG_IGN); +#endif /* !HAVE_SIGACTION */ + + block_sigchld_handler++; + +#ifdef HAVE_SIGACTION + return child_set; +#else /* !HAVE_SIGACTION */ + return 0; +#endif /* !HAVE_SIGACTION */ +} + +void +unblock_sigchld (void) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa; + sigset_t child_set; + + memset(&sa, 0, sizeof (sa)); + sa.sa_handler = SIG_DFL; + sigaction(SIGPIPE, &sa, NULL); + + sigemptyset(&child_set); + sigaddset(&child_set, SIGCHLD); + sigprocmask(SIG_UNBLOCK, &child_set, 0); + +#else /* !HAVE_SIGACTION */ + signal(SIGPIPE, SIG_DFL); +#endif /* !HAVE_SIGACTION */ + + block_sigchld_handler--; +} + +static int +kill_job (saver_info *si, pid_t pid, int signal) +{ + saver_preferences *p = &si->prefs; + struct screenhack_job *job; + int status = -1; + + clean_job_list(); + + if (block_sigchld_handler) + /* This function should not be called from the signal handler. */ + abort(); + + block_sigchld(); /* we control the horizontal... */ + + job = find_job (pid); + if (!job || + !job->pid || + job->status == job_killed) + { + if (p->verbose_p) + fprintf (stderr, "%s: no child %ld to signal!\n", + blurb(), (long) pid); + goto DONE; + } + + switch (signal) { + case SIGTERM: job->status = job_killed; break; +#ifdef SIGSTOP + /* #### there must be a way to do this on VMS... */ + case SIGSTOP: job->status = job_stopped; break; + case SIGCONT: job->status = job_running; break; +#endif /* SIGSTOP */ + default: abort(); + } + + if (p->verbose_p) + fprintf (stderr, "%s: %d: %s pid %lu (%s)\n", + blurb(), job->screen, + (job->status == job_killed ? "killing" : + job->status == job_stopped ? "suspending" : "resuming"), + (unsigned long) job->pid, + job->name); + + status = kill (job->pid, signal); + + if (p->verbose_p && status < 0) + { + if (errno == ESRCH) + fprintf (stderr, + "%s: %d: child process %lu (%s) was already dead.\n", + blurb(), job->screen, (unsigned long) job->pid, job->name); + else + { + char buf [1024]; + sprintf (buf, "%s: %d: couldn't kill child process %lu (%s)", + blurb(), job->screen, (unsigned long) job->pid, job->name); + perror (buf); + } + } + + await_dying_children (si); + + DONE: + unblock_sigchld(); + if (block_sigchld_handler < 0) + abort(); + + clean_job_list(); + return status; +} + + +#ifdef SIGCHLD +static RETSIGTYPE +sigchld_handler (int sig) +{ + saver_info *si = global_si_kludge; /* I hate C so much... */ + in_signal_handler_p++; + + if (si->prefs.debug_p) + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf(stderr, "%s: got SIGCHLD%s\n", blurb(), + (block_sigchld_handler ? " (blocked)" : "")); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": got SIGCHLD"); + + if (block_sigchld_handler) + write_string (STDERR_FILENO, " (blocked)\n"); + else + write_string (STDERR_FILENO, "\n"); + } + + if (block_sigchld_handler < 0) + abort(); + else if (block_sigchld_handler == 0) + { + block_sigchld(); + await_dying_children (si); + unblock_sigchld(); + } + + init_sigchld(); + in_signal_handler_p--; +} +#endif /* SIGCHLD */ + + +#ifndef VMS + +static void +await_dying_children (saver_info *si) +{ + while (1) + { + int wait_status = 0; + pid_t kid; + + errno = 0; + kid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED); + + if (si->prefs.debug_p) + { + if (kid < 0 && errno) + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, "%s: waitpid(-1) ==> %ld (%d)\n", blurb(), + (long) kid, errno); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": waitpid(-1) ==> "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, " ("); + write_long (STDERR_FILENO, (long) errno); + write_string (STDERR_FILENO, ")\n"); + } + else + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, "%s: waitpid(-1) ==> %ld\n", blurb(), + (long) kid); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": waitpid(-1) ==> "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, "\n"); + } + } + + /* 0 means no more children to reap. + -1 means error -- except "interrupted system call" isn't a "real" + error, so if we get that, we should just try again. */ + if (kid == 0 || + (kid < 0 && errno != EINTR)) + break; + + describe_dead_child (si, kid, wait_status); + } +} + + +static void +describe_dead_child (saver_info *si, pid_t kid, int wait_status) +{ + int i; + saver_preferences *p = &si->prefs; + struct screenhack_job *job = find_job (kid); + const char *name = job ? job->name : ""; + int screen_no = job ? job->screen : 0; + + if (WIFEXITED (wait_status)) + { + int exit_status = WEXITSTATUS (wait_status); + + /* Treat exit code as a signed 8-bit quantity. */ + if (exit_status & 0x80) exit_status |= ~0xFF; + + /* One might assume that exiting with non-0 means something went wrong. + But that loser xswarm exits with the code that it was killed with, so + it *always* exits abnormally. Treat abnormal exits as "normal" (don't + mention them) if we've just killed the subprocess. But mention them + if they happen on their own. + */ + if (!job || + (exit_status != 0 && + (p->verbose_p || job->status != job_killed))) + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, + "%s: %d: child pid %lu (%s) exited abnormally (code %d).\n", + blurb(), screen_no, (unsigned long) kid, name, exit_status); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": "); + write_long (STDERR_FILENO, (long) screen_no); + write_string (STDERR_FILENO, ": child pid "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, " ("); + write_string (STDERR_FILENO, name); + write_string (STDERR_FILENO, ") exited abnormally (code "); + write_long (STDERR_FILENO, (long) exit_status); + write_string (STDERR_FILENO, ").\n"); + } + else if (p->verbose_p) + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, "%s: %d: child pid %lu (%s) exited normally.\n", + blurb(), screen_no, (unsigned long) kid, name); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": "); + write_long (STDERR_FILENO, (long) screen_no); + write_string (STDERR_FILENO, ": child pid "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, " ("); + write_string (STDERR_FILENO, name); + write_string (STDERR_FILENO, ") exited normally.\n"); + } + + if (job) + job->status = job_dead; + } + else if (WIFSIGNALED (wait_status)) + { + if (p->verbose_p || + !job || + job->status != job_killed || + WTERMSIG (wait_status) != SIGTERM) + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, "%s: %d: child pid %lu (%s) terminated with %s.\n", + blurb(), screen_no, (unsigned long) kid, name, + signal_name (WTERMSIG(wait_status))); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": "); + write_long (STDERR_FILENO, (long) screen_no); + write_string (STDERR_FILENO, ": child pid "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, " ("); + write_string (STDERR_FILENO, name); + write_string (STDERR_FILENO, ") terminated with signal "); + write_long (STDERR_FILENO, WTERMSIG(wait_status)); + write_string (STDERR_FILENO, ".\n"); + } + + if (job) + job->status = job_dead; + } + else if (WIFSTOPPED (wait_status)) + { + if (p->verbose_p) + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, "%s: child pid %lu (%s) stopped with %s.\n", + blurb(), (unsigned long) kid, name, + signal_name (WSTOPSIG (wait_status))); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": "); + write_long (STDERR_FILENO, (long) screen_no); + write_string (STDERR_FILENO, ": child pid "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, " ("); + write_string (STDERR_FILENO, name); + write_string (STDERR_FILENO, ") stopped with signal "); + write_long (STDERR_FILENO, WSTOPSIG(wait_status)); + write_string (STDERR_FILENO, ".\n"); + } + + if (job) + job->status = job_stopped; + } + else + { + /* Don't call fprintf() from signal handlers, as it might malloc. + fprintf (stderr, "%s: child pid %lu (%s) died in a mysterious way!", + blurb(), (unsigned long) kid, name); + */ + write_string (STDERR_FILENO, blurb()); + write_string (STDERR_FILENO, ": "); + write_long (STDERR_FILENO, (long) screen_no); + write_string (STDERR_FILENO, ": child pid "); + write_long (STDERR_FILENO, (long) kid); + write_string (STDERR_FILENO, " ("); + write_string (STDERR_FILENO, name); + write_string (STDERR_FILENO, ") died in a mysterious way!"); + if (job) + job->status = job_dead; + } + + /* Clear out the pid so that screenhack_running_p() knows it's dead. + */ + if (!job || job->status == job_dead) + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (kid == ssi->pid) + ssi->pid = 0; + } +} + +#else /* VMS */ +static void await_dying_children (saver_info *si) { return; } +#endif /* VMS */ + + +void +init_sigchld (void) +{ +#ifdef SIGCHLD + +# ifdef HAVE_SIGACTION /* Thanks to Tom Kelly */ + + static Bool sigchld_initialized_p = 0; + if (!sigchld_initialized_p) + { + struct sigaction action, old; + + action.sa_handler = sigchld_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + + if (sigaction(SIGCHLD, &action, &old) < 0) + { + char buf [255]; + sprintf (buf, "%s: couldn't catch SIGCHLD", blurb()); + perror (buf); + } + sigchld_initialized_p = True; + } + +# else /* !HAVE_SIGACTION */ + + if (((long) signal (SIGCHLD, sigchld_handler)) == -1L) + { + char buf [255]; + sprintf (buf, "%s: couldn't catch SIGCHLD", blurb()); + perror (buf); + } +# endif /* !HAVE_SIGACTION */ +#endif /* SIGCHLD */ +} + + + + + +static Bool +select_visual_of_hack (saver_screen_info *ssi, screenhack *hack) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + Bool selected; + + if (hack->visual && *hack->visual) + selected = select_visual(ssi, hack->visual); + else + selected = select_visual(ssi, 0); + + if (!selected && (p->verbose_p || si->demoing_p)) + fprintf (stderr, + (si->demoing_p + ? "%s: warning, no \"%s\" visual for \"%s\".\n" + : "%s: no \"%s\" visual; skipping \"%s\".\n"), + blurb(), + (hack->visual && *hack->visual ? hack->visual : "???"), + hack->command); + + return selected; +} + + +static void +print_path_error (const char *program) +{ + char buf [512]; + char *cmd = strdup (program); + char *token = strchr (cmd, ' '); + + if (token) *token = 0; + sprintf (buf, "%s: could not execute \"%.100s\"", blurb(), cmd); + free (cmd); + perror (buf); + + if (errno == ENOENT && + (token = getenv("PATH"))) + { +# ifndef PATH_MAX +# ifdef MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# else +# define PATH_MAX 2048 +# endif +# endif + char path[PATH_MAX]; + fprintf (stderr, "\n"); + *path = 0; +# if defined(HAVE_GETCWD) + if (! getcwd (path, sizeof(path))) + *path = 0; +# elif defined(HAVE_GETWD) + getwd (path); +# endif + if (*path) + fprintf (stderr, " Current directory is: %s\n", path); + fprintf (stderr, " PATH is:\n"); + token = strtok (strdup(token), ":"); + while (token) + { + fprintf (stderr, " %s\n", token); + token = strtok(0, ":"); + } + fprintf (stderr, "\n"); + } +} + + +/* Executes the command in another process. + Command may be any single command acceptable to /bin/sh. + It may include wildcards, but no semicolons. + If successful, the pid of the other process is returned. + Otherwise, -1 is returned and an error may have been + printed to stderr. + */ +pid_t +fork_and_exec (saver_screen_info *ssi, const char *command) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + pid_t forked; + + switch ((int) (forked = fork ())) + { + case -1: + { + char buf [255]; + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + break; + } + + case 0: + close (ConnectionNumber (si->dpy)); /* close display fd */ + limit_subproc_memory (p->inferior_memory_limit, p->verbose_p); + hack_subproc_environment (ssi->screen, ssi->screensaver_window); + + if (p->verbose_p) + fprintf (stderr, "%s: %d: spawning \"%s\" in pid %lu.\n", + blurb(), ssi->number, command, + (unsigned long) getpid ()); + + exec_command (p->shell, command, p->nice_inferior); + + /* If that returned, we were unable to exec the subprocess. + Print an error message, if desired. + */ + if (! p->ignore_uninstalled_p) + print_path_error (command); + + exit (1); /* exits child fork */ + break; + + default: /* parent */ + (void) make_job (forked, ssi->number, command); + break; + } + + return forked; +} + + +void +spawn_screenhack (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + XFlush (si->dpy); + + if (!monitor_powered_on_p (si)) + { + if (si->prefs.verbose_p) + fprintf (stderr, + "%s: %d: X says monitor has powered down; " + "not launching a hack.\n", blurb(), ssi->number); + return; + } + + if (p->screenhacks_count) + { + screenhack *hack; + pid_t forked; + char buf [255]; + int new_hack = -1; + int retry_count = 0; + Bool force = False; + + AGAIN: + + if (p->screenhacks_count < 1) + { + /* No hacks at all */ + new_hack = -1; + } + else if (p->screenhacks_count == 1) + { + /* Exactly one hack in the list */ + new_hack = 0; + } + else if (si->selection_mode == -1) + { + /* Select the next hack, wrapping. */ + new_hack = (ssi->current_hack + 1) % p->screenhacks_count; + } + else if (si->selection_mode == -2) + { + /* Select the previous hack, wrapping. */ + if (ssi->current_hack < 0) + new_hack = p->screenhacks_count - 1; + else + new_hack = ((ssi->current_hack + p->screenhacks_count - 1) + % p->screenhacks_count); + } + else if (si->selection_mode > 0) + { + /* Select a specific hack, by number (via the ACTIVATE command.) */ + new_hack = ((si->selection_mode - 1) % p->screenhacks_count); + force = True; + } + else if (p->mode == ONE_HACK && + p->selected_hack >= 0) + { + /* Select a specific hack, by number (via "One Saver" mode.) */ + new_hack = p->selected_hack; + force = True; + } + else if (p->mode == BLANK_ONLY || p->mode == DONT_BLANK) + { + new_hack = -1; + } + else if (p->mode == RANDOM_HACKS_SAME && + ssi->number != 0) + { + /* Use the same hack that's running on screen 0. + (Assumes this function was called on screen 0 first.) + */ + new_hack = si->screens[0].current_hack; + } + else /* (p->mode == RANDOM_HACKS) */ + { + /* Select a random hack (but not the one we just ran.) */ + while ((new_hack = random () % p->screenhacks_count) + == ssi->current_hack) + ; + } + + if (new_hack < 0) /* don't run a hack */ + { + ssi->current_hack = -1; + if (si->selection_mode < 0) + si->selection_mode = 0; + return; + } + + ssi->current_hack = new_hack; + hack = p->screenhacks[ssi->current_hack]; + + /* If the hack is disabled, or there is no visual for this hack, + then try again (move forward, or backward, or re-randomize.) + Unless this hack was specified explicitly, in which case, + use it regardless. + */ + if (force) + select_visual_of_hack (ssi, hack); + + if (!force && + (!hack->enabled_p || + !on_path_p (hack->command) || + !select_visual_of_hack (ssi, hack))) + { + if (++retry_count > (p->screenhacks_count*4)) + { + /* Uh, oops. Odds are, there are no suitable visuals, + and we're looping. Give up. (This is totally lame, + what we should do is make a list of suitable hacks at + the beginning, then only loop over them.) + */ + if (p->verbose_p) + fprintf(stderr, + "%s: %d: no programs enabled, or no suitable visuals.\n", + blurb(), ssi->number); + return; + } + else + goto AGAIN; + } + + /* Turn off "next" and "prev" modes now, but "demo" mode is only + turned off by explicit action. + */ + if (si->selection_mode < 0) + si->selection_mode = 0; + + forked = fork_and_exec (ssi, hack->command); + switch ((int) forked) + { + case -1: /* fork failed */ + case 0: /* child fork (can't happen) */ + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + restore_real_vroot (si); + saver_exit (si, 1, "couldn't fork"); + break; + + default: + ssi->pid = forked; + break; + } + } + + store_saver_status (si); /* store current hack number */ +} + + +void +kill_screenhack (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + if (ssi->pid) + kill_job (si, ssi->pid, SIGTERM); + ssi->pid = 0; +} + + +void +suspend_screenhack (saver_screen_info *ssi, Bool suspend_p) +{ +#ifdef SIGSTOP /* older VMS doesn't have it... */ + saver_info *si = ssi->global; + if (ssi->pid) + kill_job (si, ssi->pid, (suspend_p ? SIGSTOP : SIGCONT)); +#endif /* SIGSTOP */ +} + + +/* Called when we're exiting abnormally, to kill off the subproc. */ +void +emergency_kill_subproc (saver_info *si) +{ + int i; +#ifdef SIGCHLD + signal (SIGCHLD, SIG_IGN); +#endif /* SIGCHLD */ + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->pid) + { + kill_job (si, ssi->pid, SIGTERM); + ssi->pid = 0; + } + } +} + +Bool +screenhack_running_p (saver_info *si) +{ + Bool any_running_p = False; + int i; + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->pid) any_running_p = True; + } + return any_running_p; +} + + +/* Environment variables. */ + + +/* Modifies $PATH in the current environment, so that if DEFAULT_PATH_PREFIX + is defined, the xscreensaver daemon will search that directory for hacks. + */ +void +hack_environment (saver_info *si) +{ +#if defined(HAVE_PUTENV) && defined(DEFAULT_PATH_PREFIX) + static const char *def_path = DEFAULT_PATH_PREFIX; + if (def_path && *def_path) + { + const char *opath = getenv("PATH"); + char *npath = (char *) malloc(strlen(def_path) + strlen(opath) + 20); + strcpy (npath, "PATH="); + strcat (npath, def_path); + strcat (npath, ":"); + strcat (npath, opath); + + if (putenv (npath)) + abort (); + + /* don't free (npath) -- some implementations of putenv (BSD 4.4, + glibc 2.0) copy the argument, but some (libc4,5, glibc 2.1.2) + do not. So we must leak it (and/or the previous setting). Yay. + */ + } +#endif /* HAVE_PUTENV && DEFAULT_PATH_PREFIX */ +} + + +void +hack_subproc_environment (Screen *screen, Window saver_window) +{ + /* Store $DISPLAY into the environment, so that the $DISPLAY variable that + the spawned processes inherit is correct. First, it must be on the same + host and display as the value of -display passed in on our command line + (which is not necessarily the same as what our $DISPLAY variable is.) + Second, the screen number in the $DISPLAY passed to the subprocess should + be the screen on which this particular hack is running -- not the display + specification which the driver itself is using, since the driver ignores + its screen number and manages all existing screens. + + Likewise, store a window ID in $XSCREENSAVER_WINDOW -- this will allow + us to (eventually) run multiple hacks in Xinerama mode, where each hack + has the same $DISPLAY but a different piece of glass. + */ + Display *dpy = DisplayOfScreen (screen); + const char *odpy = DisplayString (dpy); + char *ndpy = (char *) malloc (strlen(odpy) + 20); + char *nssw = (char *) malloc (40); + char *s, *c; + + strcpy (ndpy, "DISPLAY="); + s = ndpy + strlen(ndpy); + strcpy (s, odpy); + + /* We have to find the last colon since it is the boundary between + hostname & screen - IPv6 numeric format addresses may have many + colons before that point, and DECnet addresses always have two colons */ + c = strrchr(s,':'); /* skip to last colon */ + if (c != NULL) s = c+1; + while (isdigit(*s)) s++; /* skip over dpy number */ + while (*s == '.') s++; /* skip over dot */ + if (s[-1] != '.') *s++ = '.'; /* put on a dot */ + sprintf(s, "%d", screen_number (screen)); /* put on screen number */ + + sprintf (nssw, "XSCREENSAVER_WINDOW=0x%lX", (unsigned long) saver_window); + + /* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems + any more, right? It's not Posix, but everyone seems to have it. */ +#ifdef HAVE_PUTENV + if (putenv (ndpy)) + abort (); + if (putenv (nssw)) + abort (); + + /* don't free ndpy/nssw -- some implementations of putenv (BSD 4.4, + glibc 2.0) copy the argument, but some (libc4,5, glibc 2.1.2) + do not. So we must leak it (and/or the previous setting). Yay. + */ +#endif /* HAVE_PUTENV */ +} + + +/* GL crap */ + +Visual * +get_best_gl_visual (saver_info *si, Screen *screen) +{ + pid_t forked; + int fds [2]; + int in, out; + int errfds[2]; + int errin = -1, errout = -1; + char buf[1024]; + + char *av[10]; + int ac = 0; + + av[ac++] = "xscreensaver-gl-helper"; + av[ac] = 0; + + if (pipe (fds)) + { + perror ("error creating pipe:"); + return 0; + } + + in = fds [0]; + out = fds [1]; + + if (!si->prefs.verbose_p) + { + if (pipe (errfds)) + { + perror ("error creating pipe:"); + return 0; + } + + errin = errfds [0]; + errout = errfds [1]; + } + + block_sigchld(); /* This blocks it in the parent and child, to avoid + racing. It is never unblocked in the child before + the child exits, but that doesn't matter. + */ + + switch ((int) (forked = fork ())) + { + case -1: + { + sprintf (buf, "%s: couldn't fork", blurb()); + perror (buf); + saver_exit (si, 1, 0); + } + case 0: + { + close (in); /* don't need this one */ + close (ConnectionNumber (si->dpy)); /* close display fd */ + + if (dup2 (out, STDOUT_FILENO) < 0) /* pipe stdout */ + { + perror ("could not dup() a new stdout:"); + return 0; + } + + if (! si->prefs.verbose_p) + { + close(errin); + if (dup2 (errout, STDERR_FILENO) < 0) + { + perror ("could not dup() a new stderr:"); + return 0; + } + } + + hack_subproc_environment (screen, 0); /* set $DISPLAY */ + + execvp (av[0], av); /* shouldn't return. */ + + if (errno != ENOENT /* || si->prefs.verbose_p */ ) + { + /* Ignore "no such file or directory" errors. + Issue all other exec errors, though. */ + sprintf (buf, "%s: running %s", blurb(), av[0]); + perror (buf); + } + exit (1); /* exits fork */ + break; + } + default: + { + int result = 0; + int wait_status = 0; + + FILE *f = fdopen (in, "r"); + unsigned long v = 0; + char c; + + close (out); /* don't need this one */ + + *buf = 0; + if (! fgets (buf, sizeof(buf)-1, f)) + *buf = 0; + fclose (f); + + if (! si->prefs.verbose_p) + { + close (errout); + close (errin); + } + + /* Wait for the child to die. */ + waitpid (-1, &wait_status, 0); + + unblock_sigchld(); /* child is dead and waited, unblock now. */ + + if (1 == sscanf (buf, "0x%lx %c", &v, &c)) + result = (int) v; + + if (result == 0) + { + if (si->prefs.verbose_p) + { + int L = strlen(buf); + fprintf (stderr, "%s: %s did not report a GL visual!\n", + blurb(), av[0]); + + if (L && buf[L-1] == '\n') + buf[--L] = 0; + if (*buf) + fprintf (stderr, "%s: %s said: \"%s\"\n", + blurb(), av[0], buf); + } + return 0; + } + else + { + Visual *v = id_to_visual (screen, result); + if (si->prefs.verbose_p) + fprintf (stderr, "%s: %d: %s: GL visual is 0x%X%s.\n", + blurb(), screen_number (screen), + av[0], result, + (v == DefaultVisualOfScreen (screen) + ? " (default)" : "")); + return v; + } + } + } + + abort(); +} + + + +/* Restarting the xscreensaver process from scratch. */ + +static char **saved_argv; + +void +save_argv (int argc, char **argv) +{ + saved_argv = (char **) calloc (argc+2, sizeof (char *)); + saved_argv [argc] = 0; + while (argc--) + { + int i = strlen (argv [argc]) + 1; + saved_argv [argc] = (char *) malloc (i); + memcpy (saved_argv [argc], argv [argc], i); + } +} + + +/* Re-execs the process with the arguments in saved_argv. Does not return. + */ +void +restart_process (saver_info *si) +{ + fflush (stdout); + fflush (stderr); + shutdown_stderr (si); + if (si->prefs.verbose_p) + { + int i; + fprintf (stderr, "%s: re-executing", blurb()); + for (i = 0; saved_argv[i]; i++) + fprintf (stderr, " %s", saved_argv[i]); + fprintf (stderr, "\n"); + } + describe_uids (si, stderr); + fprintf (stderr, "\n"); + + fflush (stdout); + fflush (stderr); + execvp (saved_argv [0], saved_argv); /* shouldn't return */ + { + char buf [512]; + sprintf (buf, "%s: could not restart process", blurb()); + perror(buf); + fflush(stderr); + abort(); + } +} diff --git a/driver/test-apm.c b/driver/test-apm.c new file mode 100644 index 00000000..6b87c7e7 --- /dev/null +++ b/driver/test-apm.c @@ -0,0 +1,101 @@ +/* test-apm.c --- playing with the APM library. + * xscreensaver, Copyright (c) 1999 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#include +#include + +#include + +#define countof(x) (sizeof((x))/sizeof(*(x))) + + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + +static void +apm_cb (XtPointer closure, int *fd, XtInputId *id) +{ + apm_event_t events[100]; + int n, i; + while ((n = apm_get_events (*fd, 0, events, countof(events))) + > 0) + for (i = 0; i < n; i++) + { + fprintf (stderr, "%s: APM event 0x%x: %s.\n", blurb(), + events[i], apm_event_name (events[i])); +#if 0 + switch (events[i]) + { + case APM_SYS_STANDBY: + case APM_USER_STANDBY: + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + case APM_CRITICAL_SUSPEND: + break; + } +#endif + } +} + +int +main (int argc, char **argv) +{ + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + int fd; + XtInputId id; + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + fd = apm_open (); + if (fd <= 0) + { + fprintf (stderr, "%s: couldn't initialize APM.\n", blurb()); + exit (1); + } + + id = XtAppAddInput(app, fd, + (XtPointer) (XtInputReadMask | XtInputWriteMask), + apm_cb, 0); + XtAppMainLoop (app); + exit (0); +} diff --git a/driver/test-fade.c b/driver/test-fade.c new file mode 100644 index 00000000..9db773d0 --- /dev/null +++ b/driver/test-fade.c @@ -0,0 +1,123 @@ +/* test-fade.c --- playing with colormap and/or gamma fading. + * xscreensaver, Copyright (c) 2001, 2004 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include + +#include +#include "xscreensaver.h" +#include "fade.h" + +#ifdef HAVE_SGI_VC_EXTENSION +# include +#endif +#ifdef HAVE_XF86VMODE_GAMMA +# include +#endif + +XrmDatabase db = 0; +char *progname = 0; +char *progclass = "XScreenSaver"; + +#define SGI_VC_NAME "SGI-VIDEO-CONTROL" +#define XF86_VIDMODE_NAME "XFree86-VidModeExtension" + +int +main (int argc, char **argv) +{ + int seconds = 3; + int ticks = 20; + int delay = 1; + + int op, event, error, major, minor; + + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + Colormap *current_maps; + int i; + + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + db = XtDatabase (dpy); + + current_maps = (Colormap *) calloc(sizeof(Colormap), ScreenCount(dpy)); + for (i = 0; i < ScreenCount(dpy); i++) + current_maps[i] = DefaultColormap (dpy, i); + + if (!XQueryExtension (dpy, SGI_VC_NAME, &op, &event, &error)) + fprintf(stderr, "%s: no " SGI_VC_NAME " extension\n", progname); + else + { +# ifdef HAVE_SGI_VC_EXTENSION + if (!XSGIvcQueryVersion (dpy, &major, &minor)) + fprintf(stderr, "%s: unable to get " SGI_VC_NAME " version\n", + progname); + else + fprintf(stderr, "%s: " SGI_VC_NAME " version %d.%d\n", + progname, major, minor); +# else /* !HAVE_SGI_VC_EXTENSION */ + fprintf(stderr, "%s: no support for display's " SGI_VC_NAME + " extension\n", progname); +# endif /* !HAVE_SGI_VC_EXTENSION */ + } + + + if (!XQueryExtension (dpy, XF86_VIDMODE_NAME, &op, &event, &error)) + fprintf(stderr, "%s: no " XF86_VIDMODE_NAME " extension\n", progname); + else + { +# ifdef HAVE_XF86VMODE_GAMMA + if (!XF86VidModeQueryVersion (dpy, &major, &minor)) + fprintf(stderr, "%s: unable to get " XF86_VIDMODE_NAME " version\n", + progname); + else + fprintf(stderr, "%s: " XF86_VIDMODE_NAME " version %d.%d\n", + progname, major, minor); +# else /* !HAVE_XF86VMODE_GAMMA */ + fprintf(stderr, "%s: no support for display's " XF86_VIDMODE_NAME + " extension\n", progname); +# endif /* !HAVE_XF86VMODE_GAMMA */ + } + + fprintf (stderr, "%s: fading %d screen%s\n", + progname, ScreenCount(dpy), ScreenCount(dpy) == 1 ? "" : "s"); + + while (1) + { + XSync (dpy, False); + + fprintf(stderr, "%s: out...", progname); + fflush(stderr); + fade_screens (dpy, current_maps, 0, 0, seconds, ticks, True, False); + fprintf(stderr, "done.\n"); + fflush(stderr); + + if (delay) sleep (delay); + + fprintf(stderr,"%s: in...", progname); + fflush(stderr); + fade_screens (dpy, current_maps, 0, 0, seconds, ticks, False, False); + fprintf(stderr, "done.\n"); + fflush(stderr); + + if (delay) sleep (delay); + } +} diff --git a/driver/test-grab.c b/driver/test-grab.c new file mode 100644 index 00000000..03018eb5 --- /dev/null +++ b/driver/test-grab.c @@ -0,0 +1,89 @@ +/* test-uid.c --- playing with grabs. + * xscreensaver, Copyright (c) 1999, 2004 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include + +#include +#include + +char *progname = 0; +char *progclass = "XScreenSaver"; + +#define ALL_POINTER_EVENTS \ + (ButtonPressMask | ButtonReleaseMask | EnterWindowMask | \ + LeaveWindowMask | PointerMotionMask | PointerMotionHintMask | \ + Button1MotionMask | Button2MotionMask | Button3MotionMask | \ + Button4MotionMask | Button5MotionMask | ButtonMotionMask) + +int +main (int argc, char **argv) +{ + XtAppContext app; + int kstatus, mstatus; + Cursor cursor = 0; + int delay = 60 * 15; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + Window w = RootWindow (dpy, DefaultScreen(dpy)); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + kstatus = XGrabKeyboard (dpy, w, True, + GrabModeSync, GrabModeAsync, + CurrentTime); + fprintf (stderr, "%s: grabbing keyboard on 0x%lx... %s.\n", + progname, (unsigned long) w, + (kstatus == GrabSuccess ? "GrabSuccess" : + kstatus == AlreadyGrabbed ? "AlreadyGrabbed" : + kstatus == GrabInvalidTime ? "GrabInvalidTime" : + kstatus == GrabNotViewable ? "GrabNotViewable" : + kstatus == GrabFrozen ? "GrabFrozen" : + "???")); + + mstatus = XGrabPointer (dpy, w, True, ALL_POINTER_EVENTS, + GrabModeAsync, GrabModeAsync, None, + cursor, CurrentTime); + fprintf (stderr, "%s: grabbing mouse on 0x%lx... %s.\n", + progname, (unsigned long) w, + (mstatus == GrabSuccess ? "GrabSuccess" : + mstatus == AlreadyGrabbed ? "AlreadyGrabbed" : + mstatus == GrabInvalidTime ? "GrabInvalidTime" : + mstatus == GrabNotViewable ? "GrabNotViewable" : + mstatus == GrabFrozen ? "GrabFrozen" : + "???")); + + XSync(dpy, False); + + if (kstatus == GrabSuccess || mstatus == GrabSuccess) + { + fprintf (stderr, "%s: sleeping for %d:%02d:%02d...\n", + progname, + delay / (60 * 60), + (delay % (60 * 60)) / 60, + delay % 60); + fflush(stderr); + sleep (delay); + XSync(dpy, False); + } + + exit (0); +} diff --git a/driver/test-mlstring.c b/driver/test-mlstring.c new file mode 100644 index 00000000..e269a004 --- /dev/null +++ b/driver/test-mlstring.c @@ -0,0 +1,312 @@ +/* + * (c) 2007, Quest Software, Inc. All rights reserved. + * + * This file is part of XScreenSaver, + * Copyright (c) 1993-2004 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. + */ + +#include +#include +#include + +#include "mlstring.c" /* hokey, but whatever */ + +#define WRAP_WIDTH_PX 100 + +#undef Bool +#undef True +#undef False +typedef int Bool; +#define True 1 +#define False 0 + +#define SKIPPED -1 +#define SUCCESS 0 +#define FAILURE 1 + +#define FAIL(msg, ...) \ + do { \ + ++failcount; \ + fprintf(stderr, "[FAIL] "); \ + fprintf(stderr, msg, __VA_ARGS__); \ + putc('\n', stderr); \ + return FAILURE; \ + } while (0) + +#define SUCCEED(testname) \ + do { \ + fprintf(stderr, "[SUCCESS] %s\n", (testname)); \ + } while (0) + +#define SKIP(testname) \ + do { \ + fprintf(stderr, "[SKIPPED] %s\n", (testname)); \ + } while (0) + +extern mlstring* mlstring_allocate(const char *msg); +extern void mlstring_wrap(mlstring *mstr, XFontStruct *font, Dimension width); + +static int failcount = 0; + +static char *mlstring_to_cstr(const mlstring *mlstr) { + char *cstr; + size_t cstrlen = 0, alloclen = 1024; + const struct mlstr_line *line; + + cstr = malloc(alloclen); + if (!cstr) + return NULL; + cstr[0] = '\0'; + + for (line = mlstr->lines; line; line = line->next_line) { + /* Extend the buffer if necessary. */ + if (cstrlen + strlen(line->line) + 1 > alloclen) { + cstr = realloc(cstr, alloclen *= 2); + if (!cstr) + return NULL; + } + + /* If this is not the first line */ + if (line != mlstr->lines) { + /* Append a newline character */ + cstr[cstrlen] = '\n'; + ++cstrlen; + cstr[cstrlen] = '\0'; + } + + strcat(cstr, line->line); + cstrlen += strlen(line->line); + } + return cstr; +} + +/* Pass -1 for expect_min or expect_exact to not check that value. + * expect_empty_p means an empty line is expected at some point in the string. + * Also ensures that the string was not too wide after wrapping. */ +static int mlstring_expect_lines(const mlstring *mlstr, int expect_min, int expect_exact, Bool expect_empty_p) +{ + int count; + Bool got_empty_line = False; + const struct mlstr_line *line = mlstr->lines; + + for (count = 0; line; line = line->next_line) { + if (line->line[0] == '\0') { + if (!expect_empty_p) + FAIL("Not expecting empty lines, but got one on line %d of [%s]", count + 1, mlstring_to_cstr(mlstr)); + got_empty_line = True; + } + ++count; + } + + if (expect_empty_p && !got_empty_line) + FAIL("Expecting an empty line, but none found in [%s]", mlstring_to_cstr(mlstr)); + + if (expect_exact != -1 && expect_exact != count) + FAIL("Expected %d lines, got %d", expect_exact, count); + + if (expect_min != -1 && count < expect_min) + FAIL("Expected at least %d lines, got %d", expect_min, count); + + return SUCCESS; +} + +static int mlstring_expect(const char *msg, int expect_lines, const mlstring *mlstr, Bool expect_empty_p) +{ + char *str, *str_top; + const struct mlstr_line *cur; + int linecount = 0; + + /* Duplicate msg so we can chop it up */ + str_top = strdup(msg); + if (!str_top) + return SKIPPED; + + /* Replace all newlines with NUL */ + str = str_top; + while ((str = strchr(str, '\n'))) + *str++ = '\0'; + + /* str is now used to point to the expected string */ + str = str_top; + + for (cur = mlstr->lines; cur; cur = cur->next_line) + { + ++linecount; + if (strcmp(cur->line, str)) + FAIL("lines didn't match; expected [%s], got [%s]", str, cur->line); + + str += strlen(str) + 1; /* Point to the next expected string */ + } + + free(str_top); + + return mlstring_expect_lines(mlstr, -1, expect_lines, expect_empty_p); +} + +/* Ensures that the width has been set properly after wrapping */ +static int check_width(const char *msg, const mlstring *mlstr) { + if (mlstr->overall_width == 0) + FAIL("Overall width was zero for string [%s]", msg); + + if (mlstr->overall_width > WRAP_WIDTH_PX) + FAIL("Overall width was %hu but the maximum wrap width was %d", mlstr->overall_width, WRAP_WIDTH_PX); + + return SUCCESS; +} + +/* FAIL() actually returns the wrong return codes in main, but it + * prints a message which is what we want. */ + +#define TRY_NEW(str, numl, expect_empty) \ + do { \ + mlstr = mlstring_allocate((str)); \ + if (!mlstr) \ + FAIL("%s", #str); \ + if (SUCCESS == mlstring_expect((str), (numl), mlstr, (expect_empty))) \ + SUCCEED(#str); \ + free(mlstr); \ + } while (0) + +/* Expects an XFontStruct* font, and tries to wrap to 100px */ +#define TRY_WRAP(str, minl, expect_empty) \ + do { \ + mltest = mlstring_allocate((str)); \ + if (!mltest) \ + SKIP(#str); \ + else { \ + mlstring_wrap(mltest, font, WRAP_WIDTH_PX); \ + check_width((str), mltest); \ + if (SUCCESS == mlstring_expect_lines(mltest, (minl), -1, (expect_empty))) \ + SUCCEED(#str); \ + free(mltest); \ + mltest = NULL; \ + } \ + } while (0) + + +/* Ideally this function would use stub functions rather than real Xlib. + * Then it would be possible to test for exact line counts, which would be + * more reliable. + * It also doesn't handle Xlib errors. + * + * Don't print anything based on the return value of this function, it only + * returns a value so that I can use the FAIL() macro without warning. + * + * Anyone who understands this function wins a cookie ;) + */ +static int test_wrapping(void) +{ + Display *dpy = NULL; + XFontStruct *font = NULL; + mlstring *mltest = NULL; + int ok = 0; + int chars_per_line, chars_first_word, i; + + const char *test_short = "a"; + const char *test_hardwrap = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + const char *test_withnewlines = "a\nb"; + char *test_softwrap = NULL; + + dpy = XOpenDisplay(NULL); + if (!dpy) + goto end; + + font = XLoadQueryFont(dpy, "fixed"); + if (!font) + goto end; + + TRY_WRAP(test_short, 1, False); + TRY_WRAP(test_hardwrap, 2, False); + TRY_WRAP(test_withnewlines, 2, False); + + /* See if wrapping splits on word boundaries like it should */ + chars_per_line = WRAP_WIDTH_PX / font->max_bounds.width; + if (chars_per_line < 3) + goto end; + + /* Allocate for 2 lines + \0 */ + test_softwrap = malloc(chars_per_line * 2 + 1); + if (!test_softwrap) + goto end; + + /* 2 = strlen(' a'); that is, the minimum space required to start a new word + * on the same line. */ + chars_first_word = chars_per_line - 2; + + for (i = 0; i < chars_first_word; ++i) { + test_softwrap[i] = 'a'; /* first word */ + test_softwrap[i + chars_per_line] = 'b'; /* second word */ + } + /* space between first & second words */ + test_softwrap[chars_first_word] = ' '; + /* first char of second word (last char of first line) */ + test_softwrap[chars_first_word + 1] = 'b'; + /* after second word */ + test_softwrap[chars_per_line * 2] = '\0'; + + mltest = mlstring_allocate(test_softwrap); + mlstring_wrap(mltest, font, WRAP_WIDTH_PX); + + /* reusing 'i' for a moment here to make freeing mltest easier */ + i = strlen(mltest->lines->line); + free(mltest); + + if (i != chars_first_word) + FAIL("Soft wrap failed, expected the first line to be %d chars, but it was %d.", chars_first_word, i); + SUCCEED("Soft wrap"); + + ok = 1; + +end: + if (test_softwrap) + free(test_softwrap); + + if (font) + XFreeFont(dpy, font); + + if (dpy) + XCloseDisplay(dpy); + + if (!ok) + SKIP("wrapping"); + + return ok ? SUCCESS : SKIPPED; /* Unused, actually */ +} + + +int main(int argc, char *argv[]) +{ + const char *oneline = "1Foo"; + const char *twolines = "2Foo\nBar"; + const char *threelines = "3Foo\nBar\nWhippet"; + const char *trailnewline = "4Foo\n"; + const char *trailnewlines = "5Foo\n\n"; + const char *embeddednewlines = "6Foo\n\nBar"; + mlstring *mlstr; + + TRY_NEW(oneline, 1, False); + TRY_NEW(twolines, 2, False); + TRY_NEW(threelines, 3, False); + TRY_NEW(trailnewline, 2, True); + TRY_NEW(trailnewlines, 3, True); + TRY_NEW(embeddednewlines, 3, True); + + (void) test_wrapping(); + + fprintf(stdout, "%d test failures.\n", failcount); + + return !!failcount; +} + +/* vim:ts=8:sw=2:noet + */ diff --git a/driver/test-passwd.c b/driver/test-passwd.c new file mode 100644 index 00000000..66cd3d4e --- /dev/null +++ b/driver/test-passwd.c @@ -0,0 +1,305 @@ +/* xscreensaver, Copyright (c) 1998-2013 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 kludgy test harness for debugging the password dialog box. + It's somewhat easier to debug it here than in the xscreensaver executable + itself. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "xscreensaver.h" +#include "resources.h" +#include "version.h" +#include "visual.h" +#include "auth.h" + +char *progname = 0; +char *progclass = 0; +XrmDatabase db = 0; +saver_info *global_si_kludge; + +FILE *real_stderr, *real_stdout; + +void monitor_power_on (saver_info *si, Bool on_p) {} +Bool monitor_powered_on_p (saver_info *si) { return True; } +void initialize_screensaver_window (saver_info *si) {} +void raise_window (saver_info *si, Bool i, Bool b, Bool d) {} +Bool blank_screen (saver_info *si) {return False;} +void unblank_screen (saver_info *si) {} +Bool select_visual (saver_screen_info *ssi, const char *v) { return False; } +Bool window_exists_p (Display *dpy, Window window) {return True;} +void start_notice_events_timer (saver_info *si, Window w, Bool b) {} +Bool handle_clientmessage (saver_info *si, XEvent *e, Bool u) { return False; } +int BadWindow_ehandler (Display *dpy, XErrorEvent *error) { exit(1); } +const char *signal_name(int signal) { return "???"; } +Bool restore_real_vroot (saver_info *si) { return False; } +void store_saver_status (saver_info *si) {} +void saver_exit (saver_info *si, int status, const char *core) { exit(status);} +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 shutdown_stderr (saver_info *si) { } +void resize_screensaver_window (saver_info *si) { } +void describe_monitor_layout (saver_info *si) { } +Bool update_screen_layout (saver_info *si) { return 0; } +Bool in_signal_handler_p = 0; + +const char *blurb(void) { return progname; } +Atom XA_SCREENSAVER, XA_DEMO, XA_PREFS; + +void +idle_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + XEvent fake_event; + fake_event.type = 0; /* XAnyEvent type, ignored. */ + fake_event.xany.display = si->dpy; + fake_event.xany.window = 0; + XPutBackEvent (si->dpy, &fake_event); +} + + +static int +text_auth_conv ( + int num_msg, + const struct auth_message *auth_msgs, + struct auth_response **resp, + saver_info *si) +{ + char *input; + char buf[255]; + struct auth_response *responses; + int i; + + responses = calloc(num_msg, sizeof(struct auth_response)); + if (!responses) + return -1; + + /* The unlock state won't actually be used until this function returns and + * the auth module processes the response, but set it anyway for consistency + */ + si->unlock_state = ul_read; + + for (i = 0; i < num_msg; ++i) + { + printf ("\n%s: %s", progname, auth_msgs[i].msg); + if ( auth_msgs[i].type == AUTH_MSGTYPE_PROMPT_NOECHO + || auth_msgs[i].type == AUTH_MSGTYPE_PROMPT_ECHO) + { + input = fgets (buf, sizeof(buf)-1, stdin); + if (!input || !*input) + exit (0); + if (input[strlen(input)-1] == '\n') + input[strlen(input)-1] = 0; + + responses[i].response = strdup(input); + } + } + + *resp = responses; + + si->unlock_state = ul_finished; + + return 0; +} + + +#ifdef __GNUC__ + __extension__ /* shut up about "string length is greater than the length + ISO C89 compilers are required to support" when including + the .ad file... */ +#endif + +static char *fallback[] = { +#include "XScreenSaver_ad.h" + 0 +}; + +extern Bool debug_passwd_window_p; /* lock.c kludge */ + +int +main (int argc, char **argv) +{ + enum { PASS, SPLASH, TTY } which; + Widget toplevel_shell = 0; + saver_screen_info ssip; + saver_info sip; + saver_info *si = &sip; + saver_preferences *p = &si->prefs; + struct passwd *pw; + + memset(&sip, 0, sizeof(sip)); + memset(&ssip, 0, sizeof(ssip)); + + si->nscreens = 1; + si->screens = si->default_screen = &ssip; + ssip.global = si; + + global_si_kludge = si; + real_stderr = stderr; + real_stdout = stdout; + + si->version = (char *) malloc (5); + memcpy (si->version, screensaver_id + 17, 4); + si->version[4] = 0; + progname = argv[0]; + { + char *s = strrchr(progname, '/'); + if (*s) strcpy (progname, s+1); + } + + if (argc != 2) goto USAGE; + else if (!strcmp (argv[1], "pass")) which = PASS; + else if (!strcmp (argv[1], "splash")) which = SPLASH; + else if (!strcmp (argv[1], "tty")) which = TTY; + else + { + USAGE: + fprintf (stderr, "usage: %s [ pass | splash | tty ]\n", progname); + 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); + + hack_uid (si); + + if (! lock_init (argc, argv, True)) + { + si->locking_disabled_p = True; + si->nolock_reason = "error getting password"; + } +#endif + + progclass = "XScreenSaver"; + + if (!setlocale (LC_CTYPE, "")) + fprintf (stderr, "%s: warning: could not set default locale\n", + progname); + + + if (which != TTY) + { + toplevel_shell = XtAppInitialize (&si->app, progclass, 0, 0, + &argc, argv, fallback, + 0, 0); + + si->dpy = XtDisplay (toplevel_shell); + p->db = XtDatabase (si->dpy); + si->default_screen->toplevel_shell = toplevel_shell; + si->default_screen->screen = XtScreen(toplevel_shell); + si->default_screen->default_visual = + si->default_screen->current_visual = + DefaultVisualOfScreen(si->default_screen->screen); + si->default_screen->screensaver_window = + RootWindowOfScreen(si->default_screen->screen); + si->default_screen->current_depth = + visual_depth(si->default_screen->screen, + si->default_screen->current_visual); + + ssip.width = WidthOfScreen(ssip.screen); + ssip.height = HeightOfScreen(ssip.screen); + + db = p->db; + XtGetApplicationNameAndClass (si->dpy, &progname, &progclass); + + load_init_file (si->dpy, &si->prefs); + } + + p->verbose_p = True; + + pw = getpwuid (getuid ()); + si->user = strdup (pw->pw_name); + +/* si->nscreens = 0; + si->screens = si->default_screen = 0; */ + + while (1) + { +#ifndef NO_LOCKING + if (which == PASS) + { + si->unlock_cb = gui_auth_conv; + si->auth_finished_cb = auth_finished_cb; + + debug_passwd_window_p = True; + xss_authenticate(si, True); + + if (si->unlock_state == ul_success) + fprintf (stderr, "%s: authentication succeeded\n", progname); + else + fprintf (stderr, "%s: authentication FAILED!\n", progname); + + XSync(si->dpy, False); + fprintf (stderr, "\n######################################\n\n"); + sleep (3); + } + else +#endif + if (which == SPLASH) + { + XEvent event; + make_splash_dialog (si); + XtAppAddTimeOut (si->app, p->splash_duration + 1000, + idle_timer, (XtPointer) si); + while (si->splash_dialog) + { + XtAppNextEvent (si->app, &event); + if (event.xany.window == si->splash_dialog) + handle_splash_event (si, &event); + XtDispatchEvent (&event); + } + XSync (si->dpy, False); + sleep (1); + } +#ifndef NO_LOCKING + else if (which == TTY) + { + si->unlock_cb = text_auth_conv; + + printf ("%s: Authenticating user %s\n", progname, si->user); + xss_authenticate(si, True); + + if (si->unlock_state == ul_success) + printf ("%s: Ok!\n", progname); + else + printf ("%s: Wrong!\n", progname); + } +#endif + else + abort(); + } + + free(si->user); +} diff --git a/driver/test-randr.c b/driver/test-randr.c new file mode 100644 index 00000000..74ead37f --- /dev/null +++ b/driver/test-randr.c @@ -0,0 +1,339 @@ +/* test-randr.c --- playing with the Resize And Rotate extension. + * xscreensaver, Copyright (c) 2004-2008 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + + +int +main (int argc, char **argv) +{ + int event_number = -1, error_number = -1; + int major = -1, minor = -1; + int nscreens = 0; + int i; + + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + nscreens = ScreenCount(dpy); + + if (!XRRQueryExtension(dpy, &event_number, &error_number)) + { + fprintf(stderr, "%s: XRRQueryExtension(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, "%s: server does not support the RANDR extension.\n", + blurb()); + major = -1; + } + else + { + fprintf(stderr, "%s: XRRQueryExtension(dpy, ...) ==> %d, %d\n", + blurb(), event_number, error_number); + + if (!XRRQueryVersion(dpy, &major, &minor)) + { + fprintf(stderr, "%s: XRRQueryVersion(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, "%s: server didn't report RANDR version numbers?\n", + blurb()); + } + else + fprintf(stderr, "%s: XRRQueryVersion(dpy, ...) ==> %d, %d\n", blurb(), + major, minor); + } + + for (i = 0; i < nscreens; i++) + { + XRRScreenConfiguration *rrc; + XErrorHandler old_handler; + + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + rrc = (major >= 0 ? XRRGetScreenInfo (dpy, RootWindow (dpy, i)) : 0); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + if (error_handler_hit_p) + { + fprintf(stderr, "%s: XRRGetScreenInfo(dpy, %d) ==> X error:\n", + blurb(), i); + /* do it again without the error handler to print the error */ + rrc = XRRGetScreenInfo (dpy, RootWindow (dpy, i)); + } + else if (rrc) + { + SizeID current_size = -1; + Rotation current_rotation = ~0; + + fprintf (stderr, "\n%s: Screen %d\n", blurb(), i); + + current_size = + XRRConfigCurrentConfiguration (rrc, ¤t_rotation); + + /* Times */ +# if 0 /* #### This is wrong -- I don't understand what these two + timestamp numbers represent, or how they correlate + to the wall clock or to each other. */ + { + Time server_time, config_time; + server_time = XRRConfigTimes (rrc, &config_time); + if (config_time == 0 || server_time == 0) + fprintf (stderr, "%s: config has never been changed\n", + blurb()); + else + fprintf (stderr, "%s: config changed %lu seconds ago\n", + blurb(), (unsigned long) (server_time - config_time)); + } +# endif + + /* Rotations */ + { + Rotation available, current; + available = XRRConfigRotations (rrc, ¤t); + + fprintf (stderr, "%s: Available Rotations:\t", blurb()); + if (available & RR_Rotate_0) fprintf (stderr, " 0"); + if (available & RR_Rotate_90) fprintf (stderr, " 90"); + if (available & RR_Rotate_180) fprintf (stderr, " 180"); + if (available & RR_Rotate_270) fprintf (stderr, " 270"); + if (! (available & (RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270))) + fprintf (stderr, " none"); + fprintf (stderr, "\n"); + + if (current_rotation != current) + fprintf (stderr, + "%s: WARNING: rotation inconsistency: 0x%X vs 0x%X\n", + blurb(), current_rotation, current); + + fprintf (stderr, "%s: Current Rotation:\t", blurb()); + if (current & RR_Rotate_0) fprintf (stderr, " 0"); + if (current & RR_Rotate_90) fprintf (stderr, " 90"); + if (current & RR_Rotate_180) fprintf (stderr, " 180"); + if (current & RR_Rotate_270) fprintf (stderr, " 270"); + if (! (current & (RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270))) + fprintf (stderr, " none"); + fprintf (stderr, "\n"); + + fprintf (stderr, "%s: Available Reflections:\t", blurb()); + if (available & RR_Reflect_X) fprintf (stderr, " X"); + if (available & RR_Reflect_Y) fprintf (stderr, " Y"); + if (! (available & (RR_Reflect_X | RR_Reflect_Y))) + fprintf (stderr, " none"); + fprintf (stderr, "\n"); + + fprintf (stderr, "%s: Current Reflections:\t", blurb()); + if (current & RR_Reflect_X) fprintf (stderr, " X"); + if (current & RR_Reflect_Y) fprintf (stderr, " Y"); + if (! (current & (RR_Reflect_X | RR_Reflect_Y))) + fprintf (stderr, " none"); + fprintf (stderr, "\n"); + } + + /* Sizes */ + { + int nsizes, j; + XRRScreenSize *rrsizes; + + rrsizes = XRRConfigSizes (rrc, &nsizes); + if (nsizes <= 0) + fprintf (stderr, "%s: sizes:\t none\n", blurb()); + else + for (j = 0; j < nsizes; j++) + { + short *rates; + int nrates, k; + fprintf (stderr, + "%s: %c size %d: %d x %d\t rates:", + blurb(), + (j == current_size ? '+' : ' '), + j, + rrsizes[j].width, rrsizes[j].height); + + rates = XRRConfigRates (rrc, j, &nrates); + if (nrates == 0) + fprintf (stderr, " none?"); + else + for (k = 0; k < nrates; k++) + fprintf (stderr, " %d", rates[k]); + fprintf (stderr, "\n"); + /* don't free 'rates' */ + } + /* don't free 'rrsizes' */ + } + + XRRFreeScreenConfigInfo (rrc); + } + else if (major >= 0) + { + fprintf(stderr, "%s: XRRGetScreenInfo(dpy, %d) ==> NULL\n", + blurb(), i); + } + + +# ifdef HAVE_RANDR_12 + if (major > 1 || (major == 1 && minor >= 2)) + { + int j; + XRRScreenResources *res = + XRRGetScreenResources (dpy, RootWindow (dpy, i)); + fprintf (stderr, "\n"); + for (j = 0; j < res->noutput; j++) + { + int k; + XRROutputInfo *rroi = + XRRGetOutputInfo (dpy, res, res->outputs[j]); + fprintf (stderr, "%s: Output %d: %s: %s (%d)\n", blurb(), j, + rroi->name, + (rroi->connection == RR_Disconnected ? "disconnected" : + rroi->connection == RR_UnknownConnection ? "unknown" : + "connected"), + (int) rroi->crtc); + for (k = 0; k < rroi->ncrtc; k++) + { + XRRCrtcInfo *crtci = XRRGetCrtcInfo (dpy, res, + rroi->crtcs[k]); + fprintf(stderr, "%s: %c CRTC %d (%d): %dx%d+%d+%d\n", + blurb(), + (rroi->crtc == rroi->crtcs[k] ? '+' : ' '), + k, (int) rroi->crtcs[k], + crtci->width, crtci->height, crtci->x, crtci->y); + XRRFreeCrtcInfo (crtci); + } + XRRFreeOutputInfo (rroi); + fprintf (stderr, "\n"); + } + XRRFreeScreenResources (res); + } +# endif /* HAVE_RANDR_12 */ + } + + if (major > 0) + { + Window w[20]; + XWindowAttributes xgwa[20]; + + for (i = 0; i < nscreens; i++) + { + XRRSelectInput (dpy, RootWindow (dpy, i), RRScreenChangeNotifyMask); + w[i] = RootWindow (dpy, i); + XGetWindowAttributes (dpy, w[i], &xgwa[i]); + } + + XSync (dpy, False); + + fprintf (stderr, "\n%s: awaiting events...\n\n" + "\t(If you resize the screen or add/remove monitors, this should\n" + "\tnotice that and print stuff. Otherwise, hit ^C.)\n\n", + progname); + while (1) + { + XEvent event; + XNextEvent (dpy, &event); + + if (event.type == event_number + RRScreenChangeNotify) + { + XRRScreenChangeNotifyEvent *xrr_event = + (XRRScreenChangeNotifyEvent *) &event; + int screen = XRRRootToScreen (dpy, xrr_event->window); + + fprintf (stderr, "%s: screen %d: RRScreenChangeNotify event\n", + progname, screen); + + fprintf (stderr, "%s: screen %d: old size: \t%d x %d\n", + progname, screen, + DisplayWidth (dpy, screen), + DisplayHeight (dpy, screen)); + fprintf (stderr, "%s: screen %d: old root 0x%lx:\t%d x %d\n", + progname, screen, (unsigned long) w[screen], + xgwa[screen].width, xgwa[screen].height); + + XRRUpdateConfiguration (&event); + XSync (dpy, False); + + fprintf (stderr, "%s: screen %d: new size: \t%d x %d\n", + progname, screen, + DisplayWidth (dpy, screen), + DisplayHeight (dpy, screen)); + + w[screen] = RootWindow (dpy, screen); + XGetWindowAttributes (dpy, w[screen], &xgwa[screen]); + fprintf (stderr, "%s: screen %d: new root 0x%lx:\t%d x %d\n", + progname, screen, (unsigned long) w[screen], + xgwa[screen].width, xgwa[screen].height); + fprintf (stderr, "\n"); + } + else + { + fprintf (stderr, "%s: event %d\n", progname, event.type); + } + } + } + + XSync (dpy, False); + exit (0); +} diff --git a/driver/test-screens.c b/driver/test-screens.c new file mode 100644 index 00000000..2fb3e35d --- /dev/null +++ b/driver/test-screens.c @@ -0,0 +1,208 @@ +/* test-screens.c --- some test cases for the "monitor sanity" checks. + * xscreensaver, Copyright (c) 2008 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" +#include "visual.h" + +#undef WidthOfScreen +#undef HeightOfScreen +#define WidthOfScreen(s) 10240 +#define HeightOfScreen(s) 10240 + +#undef screen_number +#define screen_number(s) ((int) s) + +#include "screens.c" /* to get at static void check_monitor_sanity() */ + +char *progname = 0; +char *progclass = "XScreenSaver"; + +const char *blurb(void) { return progname; } + +Bool safe_XF86VidModeGetViewPort(Display *d, int i, int *x, int *y) { abort(); } +void initialize_screen_root_widget(saver_screen_info *ssi) { abort(); } +Visual *get_best_gl_visual (saver_info *si, Screen *sc) { abort(); } + + +static const char * +failstr (monitor_sanity san) +{ + switch (san) { + case S_SANE: return "OK"; + case S_ENCLOSED: return "ENC"; + case S_DUPLICATE: return "DUP"; + case S_OVERLAP: return "OVR"; + case S_OFFSCREEN: return "OFF"; + case S_DISABLED: return "DIS"; + default: abort(); break; + } +} + + +static void +test (int testnum, const char *screens, const char *desired) +{ + monitor *monitors[100]; + char result[2048]; + char *out = result; + int i, nscreens = 0; + char *token = strtok (strdup(screens), ","); + while (token) + { + monitor *m = calloc (1, sizeof (monitor)); + char c; + m->id = (testnum * 1000) + nscreens; + if (5 == sscanf (token, "%dx%d+%d+%d@%d%c", + &m->width, &m->height, &m->x, &m->y, + (int *) &m->screen, &c)) + ; + else if (4 != sscanf (token, "%dx%d+%d+%d%c", + &m->width, &m->height, &m->x, &m->y, &c)) + { + fprintf (stderr, "%s: unparsable geometry: %s\n", blurb(), token); + exit (1); + } + monitors[nscreens] = m; + nscreens++; + token = strtok (0, ","); + } + monitors[nscreens] = 0; + + check_monitor_sanity (monitors); + + *out = 0; + for (i = 0; i < nscreens; i++) + { + monitor *m = monitors[i]; + if (out != result) *out++ = ','; + if (m->sanity == S_SANE) + { + sprintf (out, "%dx%d+%d+%d", m->width, m->height, m->x, m->y); + if (m->screen) + sprintf (out + strlen(out), "@%d", (int) m->screen); + } + else + strcpy (out, failstr (m->sanity)); + out += strlen(out); + } + *out = 0; + + if (!strcmp (result, desired)) + fprintf (stderr, "%s: test %2d OK\n", blurb(), testnum); + else + fprintf (stderr, "%s: test %2d FAILED:\n" + "%s: given: %s\n" + "%s: wanted: %s\n" + "%s: got: %s\n", + blurb(), testnum, + blurb(), screens, + blurb(), desired, + blurb(), result); + +# if 0 + { + saver_info SI; + SI.monitor_layout = monitors; + describe_monitor_layout (&SI); + } +# endif + +} + +static void +run_tests(void) +{ + int i = 1; +# define A(a) test (i++, a, a); +# define B(a,b) test (i++, a, b) + + A(""); + A("1024x768+0+0"); + A("1024x768+0+0,1024x768+1024+0"); + A("1024x768+0+0,1024x768+0+768"); + A("1024x768+0+0,1024x768+0+768,1024x768+1024+0"); + A("800x600+0+0,800x600+0+0@1,800x600+10+0@2"); + + B("1024x768+999999+0", + "OFF"); + B("1024x768+-999999+-999999", + "OFF"); + B("1024x768+0+0,1024x768+0+0", + "1024x768+0+0,DUP"); + B("1024x768+0+0,1024x768+0+0,1024x768+0+0", + "1024x768+0+0,DUP,DUP"); + B("1024x768+0+0,1024x768+1024+0,1024x768+0+0", + "1024x768+0+0,1024x768+1024+0,DUP"); + B("1280x1024+0+0,1024x768+0+64,800x600+0+0,640x480+0+0,720x400+0+0", + "1280x1024+0+0,ENC,ENC,ENC,ENC"); + B("1024x768+0+64,1280x1024+0+0,800x600+0+0,640x480+0+0,800x600+0+0,720x400+0+0", + "ENC,1280x1024+0+0,ENC,ENC,ENC,ENC"); + B("1024x768+0+64,1280x1024+0+0,800x600+0+0,640x480+0+0,1280x1024+0+0,720x400+0+0", + "ENC,1280x1024+0+0,ENC,ENC,DUP,ENC"); + B("720x400+0+0,640x480+0+0,800x600+0+0,1024x768+0+64,1280x1024+0+0", + "ENC,ENC,ENC,ENC,1280x1024+0+0"); + B("1280x1024+0+0,800x600+1280+0,800x600+1300+0", + "1280x1024+0+0,800x600+1280+0,OVR"); + B("1280x1024+0+0,800x600+1280+0,800x600+1300+0,1280x1024+0+0,800x600+1280+0", + "1280x1024+0+0,800x600+1280+0,OVR,DUP,DUP"); + + /* +-------------+----+ +------+---+ 1: 1440x900, widescreen display + | : | | 3+4 : | 2: 1280x1024, conventional display + | 1+2 : 1 | +......+ | 3: 1024x768, laptop + | : | | 3 | 4: 800x600, external projector + +.............+----+ +----------+ + | 2 | + | | + +-------------+ + */ + B("1440x900+0+0,1280x1024+0+0,1024x768+1440+0,800x600+1440+0", + "1440x900+0+0,OVR,1024x768+1440+0,ENC"); + B("800x600+0+0,800x600+0+0,800x600+800+0", + "800x600+0+0,DUP,800x600+800+0"); + B("1600x1200+0+0,1360x768+0+0", + "1600x1200+0+0,ENC"); + B("1600x1200+0+0,1360x768+0+0,1600x1200+0+0@1,1360x768+0+0@1", + "1600x1200+0+0,ENC,1600x1200+0+0@1,ENC"); +} + + +int +main (int argc, char **argv) +{ + char *s; + progname = argv[0]; + s = strrchr(progname, '/'); + if (s) progname = s+1; + if (argc != 1) + { + fprintf (stderr, "usage: %s\n", argv[0]); + exit (1); + } + + run_tests(); + + exit (0); +} diff --git a/driver/test-uid.c b/driver/test-uid.c new file mode 100644 index 00000000..6a1f9cc1 --- /dev/null +++ b/driver/test-uid.c @@ -0,0 +1,209 @@ +/* test-uid.c --- playing with setuid. + * xscreensaver, Copyright (c) 1998, 2005 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +static void +print(void) +{ + int uid = getuid(); + int gid = getgid(); + int euid = geteuid(); + int egid = getegid(); + struct passwd *p = 0; + struct group *g = 0; + gid_t groups[1024]; + int n, size; + + p = getpwuid (uid); + g = getgrgid (gid); + fprintf(stderr, "real user/group: %ld/%ld (%s/%s)\n", (long) uid, (long) gid, + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???")); + + p = getpwuid (euid); + g = getgrgid (egid); + fprintf(stderr, "eff. user/group: %ld/%ld (%s/%s)\n", (long)euid, (long)egid, + (p && p->pw_name ? p->pw_name : "???"), + (g && g->gr_name ? g->gr_name : "???")); + + size = sizeof(groups) / sizeof(gid_t); + n = getgroups(size - 1, groups); + if (n < 0) + perror("getgroups failed"); + else + { + int i; + fprintf (stderr, "eff. group list: ["); + for (i = 0; i < n; i++) + { + g = getgrgid (groups[i]); + fprintf(stderr, "%s%s=%ld", (i == 0 ? "" : ", "), + (g->gr_name ? g->gr_name : "???"), + (long) groups[i]); + } + fprintf (stderr, "]\n"); + } +} + +int +main (int argc, char **argv) +{ + int i; + struct passwd *p = 0; + struct group *g = 0; + + if (argc <= 1) + { + fprintf(stderr, + "usage: %s [ user/group ... ]\n" + "\tEach argument may be a user name, or user/group.\n" + "\tThis program will attempt to setuid/setgid to each\n" + "\tin turn, and report the results. The user and group\n" + "\tnames may be strings, or numeric.\n", + argv[0]); + exit(1); + } + + print(); + for (i = 1; i < argc; i++) + { + char *user = argv[i]; + char *group = strchr(user, '/'); + if (!group) + group = strchr(user, '.'); + if (group) + *group++ = 0; + + if (group && *group) + { + long gid = 0; + int was_numeric = 0; + + g = 0; + if (*group == '-' || (*group >= '0' && *group <= '9')) + if (1 == sscanf(group, "%ld", &gid)) + { + g = getgrgid (gid); + was_numeric = 1; + } + + if (!g) + g = getgrnam(group); + + if (g) + { + gid = g->gr_gid; + group = g->gr_name; + } + else + { + if (was_numeric) + { + fprintf(stderr, "no group numbered %s.\n", group); + group = ""; + } + else + { + fprintf(stderr, "no group named %s.\n", group); + goto NOGROUP; + } + } + + fprintf(stderr, "setgroups(1, [%ld]) \"%s\"", gid, group); + { + gid_t g2 = gid; + if (setgroups(1, &g2) == 0) + fprintf(stderr, " succeeded.\n"); + else + perror(" failed"); + } + + fprintf(stderr, "setgid(%ld) \"%s\"", gid, group); + if (setgid(gid) == 0) + fprintf(stderr, " succeeded.\n"); + else + perror(" failed"); + + NOGROUP: ; + } + + if (user && *user) + { + long uid = 0; + int was_numeric = 0; + + p = 0; + if (*user == '-' || (*user >= '0' && *user <= '9')) + if (1 == sscanf(user, "%ld", &uid)) + { + p = getpwuid (uid); + was_numeric = 1; + } + + if (!p) + p = getpwnam(user); + + if (p) + { + uid = p->pw_uid; + user = p->pw_name; + } + else + { + if (was_numeric) + { + fprintf(stderr, "no user numbered \"%s\".\n", user); + user = ""; + } + else + { + fprintf(stderr, "no user named %s.\n", user); + goto NOUSER; + } + } + + fprintf(stderr, "setuid(%ld) \"%s\"", uid, user); + if (setuid(uid) == 0) + fprintf(stderr, " succeeded.\n"); + else + perror(" failed"); + NOUSER: ; + } + print(); + } + + fprintf(stderr, + "running \"whoami\" and \"groups\" in a sub-process reports:\n"); + fflush(stdout); + fflush(stderr); + system ("/bin/sh -c 'echo \"`whoami` / `groups`\"'"); + + fflush(stdout); + fflush(stderr); + exit(0); +} diff --git a/driver/test-vp.c b/driver/test-vp.c new file mode 100644 index 00000000..bf1a0b18 --- /dev/null +++ b/driver/test-vp.c @@ -0,0 +1,213 @@ +/* test-xinerama.c --- playing with XF86VidModeGetViewPort + * xscreensaver, Copyright (c) 2004 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + + +static int +screen_count (Display *dpy) +{ + int n = ScreenCount(dpy); + int xn = 0; + int event_number, error_number; + + if (!XineramaQueryExtension (dpy, &event_number, &error_number)) + { + fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...) ==> False\n", + blurb()); + goto DONE; + } + else + fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...) ==> %d, %d\n", + blurb(), event_number, error_number); + + if (!XineramaIsActive(dpy)) + { + fprintf(stderr, "%s: XineramaIsActive(dpy) ==> False\n", + blurb()); + goto DONE; + } + else + { + int major, minor; + XineramaScreenInfo *xsi; + fprintf(stderr, "%s: XineramaIsActive(dpy) ==> True\n", + blurb()); + if (!XineramaQueryVersion(dpy, &major, &minor)) + { + fprintf(stderr, + "%s: XineramaQueryVersion(dpy, ...) ==> False\n", + blurb()); + goto DONE; + } + else + fprintf(stderr, + "%s: XineramaQueryVersion(dpy, ...) ==> %d, %d\n", + blurb(), major, minor); + + xsi = XineramaQueryScreens (dpy, &xn); + if (xsi) XFree (xsi); + } + + DONE: + fprintf (stderr, "\n"); + fprintf (stderr, "%s: X client screens: %d\n", blurb(), n); + fprintf (stderr, "%s: Xinerama screens: %d\n", blurb(), xn); + fprintf (stderr, "\n"); + + if (xn > n) return xn; + else return n; +} + + +int +main (int argc, char **argv) +{ + int event_number, error_number; + int major, minor; + int nscreens = 0; + int i; + + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + if (!XF86VidModeQueryExtension(dpy, &event_number, &error_number)) + { + fprintf(stderr, "%s: XF86VidModeQueryExtension(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, + "%s: server does not support the XF86VidMode extension.\n", + blurb()); + exit(1); + } + else + fprintf(stderr, "%s: XF86VidModeQueryExtension(dpy, ...) ==> %d, %d\n", + blurb(), event_number, error_number); + + if (!XF86VidModeQueryVersion(dpy, &major, &minor)) + { + fprintf(stderr, "%s: XF86VidModeQueryVersion(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, + "%s: server didn't report XF86VidMode version numbers?\n", + blurb()); + } + else + fprintf(stderr, "%s: XF86VidModeQueryVersion(dpy, ...) ==> %d, %d\n", + blurb(), major, minor); + + nscreens = screen_count (dpy); + + for (i = 0; i < nscreens; i++) + { + int result = 0; + int x = 0, y = 0, dot = 0; + XF86VidModeModeLine ml = { 0, }; + XErrorHandler old_handler; + + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + result = XF86VidModeGetViewPort (dpy, i, &x, &y); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + if (error_handler_hit_p) + { + fprintf(stderr, + "%s: XF86VidModeGetViewPort(dpy, %d, ...) ==> X error\n", + blurb(), i); + continue; + } + + if (! result) + fprintf(stderr, "%s: XF86VidModeGetViewPort(dpy, %d, ...) ==> %d\n", + blurb(), i, result); + + result = XF86VidModeGetModeLine (dpy, i, &dot, &ml); + if (! result) + fprintf(stderr, "%s: XF86VidModeGetModeLine(dpy, %d, ...) ==> %d\n", + blurb(), i, result); + + fprintf (stderr, "%s: screen %d: %dx%d; viewport: %dx%d+%d+%d\n", + blurb(), i, + DisplayWidth (dpy, i), DisplayHeight (dpy, i), + ml.hdisplay, ml.vdisplay, x, y + ); + + fprintf (stderr, + "%s: hsync start %d; end %d; total %d; skew %d;\n", + blurb(), + ml.hsyncstart, ml.hsyncend, ml.htotal, ml.hskew); + fprintf (stderr, + "%s: vsync start %d; end %d; total %d; flags 0x%04x;\n", + blurb(), + ml.vsyncstart, ml.vsyncend, ml.vtotal, ml.flags); + fprintf (stderr, "\n"); + } + XSync (dpy, False); + exit (0); +} diff --git a/driver/test-xdpms.c b/driver/test-xdpms.c new file mode 100644 index 00000000..b86aed3a --- /dev/null +++ b/driver/test-xdpms.c @@ -0,0 +1,179 @@ +/* test-xdpms.c --- playing with the XDPMS extension. + * xscreensaver, Copyright (c) 1998-2011 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern Bool DPMSQueryExtension (Display *dpy, int *event_ret, int *error_ret); +extern Bool DPMSCapable (Display *dpy); +extern Status DPMSForceLevel (Display *dpy, CARD16 level); +extern Status DPMSInfo (Display *dpy, CARD16 *power_level, BOOL *state); + +extern Status DPMSGetVersion (Display *dpy, int *major_ret, int *minor_ret); +extern Status DPMSSetTimeouts (Display *dpy, + CARD16 standby, CARD16 suspend, CARD16 off); +extern Bool DPMSGetTimeouts (Display *dpy, + CARD16 *standby, CARD16 *suspend, CARD16 *off); +extern Status DPMSEnable (Display *dpy); +extern Status DPMSDisable (Display *dpy); + + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + + +int +main (int argc, char **argv) +{ + int delay = 10; + + int event_number, error_number; + int major, minor; + CARD16 standby, suspend, off; + CARD16 state; + BOOL onoff; + + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + if (!DPMSQueryExtension(dpy, &event_number, &error_number)) + { + fprintf(stderr, "%s: DPMSQueryExtension(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, "%s: server does not support the XDPMS extension.\n", + blurb()); + exit(1); + } + else + fprintf(stderr, "%s: DPMSQueryExtension(dpy, ...) ==> %d, %d\n", blurb(), + event_number, error_number); + + if (!DPMSCapable(dpy)) + { + fprintf(stderr, "%s: DPMSCapable(dpy) ==> False\n", blurb()); + fprintf(stderr, "%s: server says hardware doesn't support DPMS.\n", + blurb()); + exit(1); + } + else + fprintf(stderr, "%s: DPMSCapable(dpy) ==> True\n", blurb()); + + if (!DPMSGetVersion(dpy, &major, &minor)) + { + fprintf(stderr, "%s: DPMSGetVersion(dpy, ...) ==> False\n", blurb()); + fprintf(stderr, "%s: server didn't report XDPMS version numbers?\n", + blurb()); + } + else + fprintf(stderr, "%s: DPMSGetVersion(dpy, ...) ==> %d, %d\n", blurb(), + major, minor); + + if (!DPMSGetTimeouts(dpy, &standby, &suspend, &off)) + { + fprintf(stderr, "%s: DPMSGetTimeouts(dpy, ...) ==> False\n", blurb()); + fprintf(stderr, "%s: server didn't report DPMS timeouts?\n", blurb()); + } + else + fprintf(stderr, + "%s: DPMSGetTimeouts(dpy, ...)\n" + "\t ==> standby = %d, suspend = %d, off = %d\n", + blurb(), standby, suspend, off); + + while (1) + { + if (!DPMSInfo(dpy, &state, &onoff)) + { + fprintf(stderr, "%s: DPMSInfo(dpy, ...) ==> False\n", blurb()); + fprintf(stderr, "%s: couldn't read DPMS state?\n", blurb()); + onoff = 0; + state = -1; + } + else + { + fprintf(stderr, "%s: DPMSInfo(dpy, ...) ==> %s, %s\n", blurb(), + (state == DPMSModeOn ? "DPMSModeOn" : + state == DPMSModeStandby ? "DPMSModeStandby" : + state == DPMSModeSuspend ? "DPMSModeSuspend" : + state == DPMSModeOff ? "DPMSModeOff" : "???"), + (onoff == 1 ? "On" : onoff == 0 ? "Off" : "???")); + } + + if (state == DPMSModeStandby || + state == DPMSModeSuspend || + state == DPMSModeOff) + { + XErrorHandler old_handler; + int st; + fprintf(stderr, "%s: monitor is off; turning it on.\n", blurb()); + + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + XSync (dpy, False); + st = DPMSForceLevel (dpy, DPMSModeOn); + XSync (dpy, False); + if (error_handler_hit_p) st = -666; + + fprintf (stderr, "%s: DPMSForceLevel (dpy, DPMSModeOn) ==> %s\n", + blurb(), (st == -666 ? "X Error" : st ? "Ok" : "Error")); + } + + sleep (delay); + } +} diff --git a/driver/test-xinerama.c b/driver/test-xinerama.c new file mode 100644 index 00000000..8bafbb07 --- /dev/null +++ b/driver/test-xinerama.c @@ -0,0 +1,112 @@ +/* test-xinerama.c --- playing with the Xinerama extension. + * xscreensaver, Copyright (c) 2003 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include + +char *progname = 0; +char *progclass = "XScreenSaver"; + +static const char * +blurb (void) +{ + static char buf[255]; + time_t now = time ((time_t *) 0); + char *ct = (char *) ctime (&now); + int n = strlen(progname); + if (n > 100) n = 99; + strncpy(buf, progname, n); + buf[n++] = ':'; + buf[n++] = ' '; + strncpy(buf+n, ct+11, 8); + strcpy(buf+n+9, ": "); + return buf; +} + + +int +main (int argc, char **argv) +{ + int event_number, error_number; + int major, minor; + int nscreens = 0; + XineramaScreenInfo *xsi; + int i; + + XtAppContext app; + Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, + &argc, argv, 0, 0, 0); + Display *dpy = XtDisplay (toplevel_shell); + XtGetApplicationNameAndClass (dpy, &progname, &progclass); + + if (!XineramaQueryExtension(dpy, &event_number, &error_number)) + { + fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, "%s: server does not support the Xinerama extension.\n", + blurb()); + exit(1); + } + else + fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...) ==> %d, %d\n", + blurb(), event_number, error_number); + + if (!XineramaIsActive(dpy)) + { + fprintf(stderr, "%s: XineramaIsActive(dpy) ==> False\n", blurb()); + fprintf(stderr, "%s: server says Xinerama is turned off.\n", blurb()); + exit(1); + } + else + fprintf(stderr, "%s: XineramaIsActive(dpy) ==> True\n", blurb()); + + if (!XineramaQueryVersion(dpy, &major, &minor)) + { + fprintf(stderr, "%s: XineramaQueryVersion(dpy, ...) ==> False\n", + blurb()); + fprintf(stderr, "%s: server didn't report Xinerama version numbers?\n", + blurb()); + } + else + fprintf(stderr, "%s: XineramaQueryVersion(dpy, ...) ==> %d, %d\n", blurb(), + major, minor); + + xsi = XineramaQueryScreens (dpy, &nscreens); + fprintf(stderr, "%s: %d Xinerama screens\n", blurb(), nscreens); + + for (i = 0; i < nscreens; i++) + fprintf (stderr, "%s: screen %d: %dx%d+%d+%d\n", + blurb(), + xsi[i].screen_number, + xsi[i].width, xsi[i].height, + xsi[i].x_org, xsi[i].y_org); + XFree (xsi); + XSync (dpy, False); + exit (0); +} diff --git a/driver/timers.c b/driver/timers.c new file mode 100644 index 00000000..5489bef6 --- /dev/null +++ b/driver/timers.c @@ -0,0 +1,1676 @@ +/* timers.c --- detecting when the user is idle, and other timer-related tasks. + * xscreensaver, Copyright (c) 1991-2013 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_XMU +# ifndef VMS +# include +# else /* VMS */ +# include +# endif /* VMS */ +# else /* !HAVE_XMU */ +# include "xmu.h" +#endif /* !HAVE_XMU */ + +#ifdef HAVE_XIDLE_EXTENSION +#include +#endif /* HAVE_XIDLE_EXTENSION */ + +#ifdef HAVE_MIT_SAVER_EXTENSION +#include +#endif /* HAVE_MIT_SAVER_EXTENSION */ + +#ifdef HAVE_SGI_SAVER_EXTENSION +#include +#endif /* HAVE_SGI_SAVER_EXTENSION */ + +#ifdef HAVE_RANDR +#include +#endif /* HAVE_RANDR */ + +#include "xscreensaver.h" + +#undef ABS +#define ABS(x)((x)<0?-(x):(x)) + +#undef MAX +#define MAX(x,y)((x)>(y)?(x):(y)) + + +#ifdef HAVE_PROC_INTERRUPTS +static Bool proc_interrupts_activity_p (saver_info *si); +#endif /* HAVE_PROC_INTERRUPTS */ + +static void check_for_clock_skew (saver_info *si); + + +void +idle_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + + /* What an amazingly shitty design. Not only does Xt execute timeout + events from XtAppNextEvent() instead of from XtDispatchEvent(), but + there is no way to tell Xt to block until there is an X event OR a + timeout happens. Once your timeout proc is called, XtAppNextEvent() + still won't return until a "real" X event comes in. + + So this function pushes a stupid, gratuitous, unnecessary event back + on the event queue to force XtAppNextEvent to return Right Fucking Now. + When the code in sleep_until_idle() sees an event of type XAnyEvent, + which the server never generates, it knows that a timeout has occurred. + */ + XEvent fake_event; + fake_event.type = 0; /* XAnyEvent type, ignored. */ + fake_event.xany.display = si->dpy; + fake_event.xany.window = 0; + XPutBackEvent (si->dpy, &fake_event); + + /* If we are the timer that just went off, clear the pointer to the id. */ + if (id) + { + if (si->timer_id && *id != si->timer_id) + abort(); /* oops, scheduled timer twice?? */ + si->timer_id = 0; + } +} + + +void +schedule_wakeup_event (saver_info *si, Time when, Bool verbose_p) +{ + if (si->timer_id) + { + if (verbose_p) + fprintf (stderr, "%s: idle_timer already running\n", blurb()); + return; + } + + /* Wake up periodically to ask the server if we are idle. */ + si->timer_id = XtAppAddTimeOut (si->app, when, idle_timer, + (XtPointer) si); + + if (verbose_p) + fprintf (stderr, "%s: starting idle_timer (%ld, %ld)\n", + blurb(), when, si->timer_id); +} + + +static void +notice_events (saver_info *si, Window window, Bool top_p) +{ + saver_preferences *p = &si->prefs; + XWindowAttributes attrs; + unsigned long events; + Window root, parent, *kids; + unsigned int nkids; + int screen_no; + + if (XtWindowToWidget (si->dpy, window)) + /* If it's one of ours, don't mess up its event mask. */ + return; + + if (!XQueryTree (si->dpy, window, &root, &parent, &kids, &nkids)) + return; + if (window == root) + top_p = False; + + /* Figure out which screen this window is on, for the diagnostics. */ + for (screen_no = 0; screen_no < si->nscreens; screen_no++) + if (root == RootWindowOfScreen (si->screens[screen_no].screen)) + break; + + XGetWindowAttributes (si->dpy, window, &attrs); + events = ((attrs.all_event_masks | attrs.do_not_propagate_mask) + & KeyPressMask); + + /* Select for SubstructureNotify on all windows. + Select for KeyPress on all windows that already have it selected. + + Note that we can't select for ButtonPress, because of X braindamage: + only one client at a time may select for ButtonPress on a given + window, though any number can select for KeyPress. Someone explain + *that* to me. + + So, if the user spends a while clicking the mouse without ever moving + the mouse or touching the keyboard, we won't know that they've been + active, and the screensaver will come on. That sucks, but I don't + know how to get around it. + + Since X presents mouse wheels as clicks, this applies to those, too: + scrolling through a document using only the mouse wheel doesn't + count as activity... Fortunately, /proc/interrupts helps, on + systems that have it. Oh, if it's a PS/2 mouse, not serial or USB. + This sucks! + */ + XSelectInput (si->dpy, window, SubstructureNotifyMask | events); + + if (top_p && p->debug_p && (events & KeyPressMask)) + { + /* Only mention one window per tree (hack hack). */ + fprintf (stderr, "%s: %d: selected KeyPress on 0x%lX\n", + blurb(), screen_no, (unsigned long) window); + top_p = False; + } + + if (kids) + { + while (nkids) + notice_events (si, kids [--nkids], top_p); + XFree ((char *) kids); + } +} + + +int +BadWindow_ehandler (Display *dpy, XErrorEvent *error) +{ + /* When we notice a window being created, we spawn a timer that waits + 30 seconds or so, and then selects events on that window. This error + handler is used so that we can cope with the fact that the window + may have been destroyed <30 seconds after it was created. + */ + if (error->error_code == BadWindow || + error->error_code == BadMatch || + error->error_code == BadDrawable) + return 0; + else + return saver_ehandler (dpy, error); +} + + +struct notice_events_timer_arg { + saver_info *si; + Window w; +}; + +static void +notice_events_timer (XtPointer closure, XtIntervalId *id) +{ + struct notice_events_timer_arg *arg = + (struct notice_events_timer_arg *) closure; + + XErrorHandler old_handler = XSetErrorHandler (BadWindow_ehandler); + + saver_info *si = arg->si; + Window window = arg->w; + + free(arg); + notice_events (si, window, True); + XSync (si->dpy, False); + XSetErrorHandler (old_handler); +} + +void +start_notice_events_timer (saver_info *si, Window w, Bool verbose_p) +{ + saver_preferences *p = &si->prefs; + struct notice_events_timer_arg *arg = + (struct notice_events_timer_arg *) malloc(sizeof(*arg)); + arg->si = si; + arg->w = w; + XtAppAddTimeOut (si->app, p->notice_events_timeout, notice_events_timer, + (XtPointer) arg); + + if (verbose_p) + fprintf (stderr, "%s: starting notice_events_timer for 0x%X (%lu)\n", + blurb(), (unsigned int) w, p->notice_events_timeout); +} + + +/* When the screensaver is active, this timer will periodically change + the running program. + */ +void +cycle_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + Time how_long = p->cycle; + + if (si->selection_mode > 0 && + screenhack_running_p (si)) + /* If we're in "SELECT n" mode, the cycle timer going off will just + restart this same hack again. There's not much point in doing this + every 5 or 10 minutes, but on the other hand, leaving one hack running + for days is probably not a great idea, since they tend to leak and/or + crash. So, restart the thing once an hour. */ + how_long = 1000 * 60 * 60; + + if (si->dbox_up_p) + { + if (p->verbose_p) + fprintf (stderr, "%s: dialog box up; delaying hack change.\n", + blurb()); + how_long = 30000; /* 30 secs */ + } + else + { + int i; + maybe_reload_init_file (si); + for (i = 0; i < si->nscreens; i++) + kill_screenhack (&si->screens[i]); + + raise_window (si, True, True, False); + + if (!si->throttled_p) + for (i = 0; i < si->nscreens; i++) + spawn_screenhack (&si->screens[i]); + else + { + if (p->verbose_p) + fprintf (stderr, "%s: not launching new hack (throttled.)\n", + blurb()); + } + } + + if (how_long > 0) + { + si->cycle_id = XtAppAddTimeOut (si->app, how_long, cycle_timer, + (XtPointer) si); + + if (p->debug_p) + fprintf (stderr, "%s: starting cycle_timer (%ld, %ld)\n", + blurb(), how_long, si->cycle_id); + } + else + { + if (p->debug_p) + fprintf (stderr, "%s: not starting cycle_timer: how_long == %ld\n", + blurb(), (unsigned long) how_long); + } +} + + +void +activate_lock_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + + if (p->verbose_p) + fprintf (stderr, "%s: timed out; activating lock.\n", blurb()); + set_locked_p (si, True); +} + + +/* Call this when user activity (or "simulated" activity) has been noticed. + */ +void +reset_timers (saver_info *si) +{ + saver_preferences *p = &si->prefs; + if (si->using_mit_saver_extension || si->using_sgi_saver_extension) + return; + + if (si->timer_id) + { + if (p->debug_p) + fprintf (stderr, "%s: killing idle_timer (%ld, %ld)\n", + blurb(), p->timeout, si->timer_id); + XtRemoveTimeOut (si->timer_id); + si->timer_id = 0; + } + + schedule_wakeup_event (si, p->timeout, p->debug_p); /* sets si->timer_id */ + + if (si->cycle_id) abort (); /* no cycle timer when inactive */ + + si->last_activity_time = time ((time_t *) 0); + + /* This will (hopefully, supposedly) tell the server to re-set its + DPMS timer. Without this, the -deactivate clientmessage would + prevent xscreensaver from blanking, but would not prevent the + monitor from powering down. */ +#if 0 + /* #### With some servers, this causes the screen to flicker every + time a key is pressed! Ok, I surrender. I give up on ever + having DPMS work properly. + */ + XForceScreenSaver (si->dpy, ScreenSaverReset); + + /* And if the monitor is already powered off, turn it on. + You'd think the above would do that, but apparently not? */ + monitor_power_on (si, True); +#endif + +} + + +/* Returns true if a mouse has moved since the last time we checked. + Small motions (of less than "hysteresis" pixels/second) are ignored. + */ +static Bool +device_pointer_moved_p (saver_info *si, poll_mouse_data *last_poll_mouse, + poll_mouse_data *this_poll_mouse, Bool mods_p, + const char *debug_type, int debug_id) +{ + saver_preferences *p = &si->prefs; + + unsigned int distance, dps; + unsigned long seconds = 0; + Bool moved_p = False; + + distance = MAX (ABS (last_poll_mouse->root_x - this_poll_mouse->root_x), + ABS (last_poll_mouse->root_y - this_poll_mouse->root_y)); + seconds = (this_poll_mouse->time - last_poll_mouse->time); + + + /* When the screen is blanked, we get MotionNotify events, but when not + blanked, we poll only every 5 seconds, and that's not enough resolution + to do hysteresis based on a 1 second interval. So, assume that any + motion we've seen during the 5 seconds when our eyes were closed happened + in the last 1 second instead. + */ + if (seconds > 1) seconds = 1; + + dps = (seconds <= 0 ? distance : (distance / seconds)); + + /* Motion only counts if the rate is more than N pixels per second. + */ + if (dps >= p->pointer_hysteresis && + distance > 0) + moved_p = True; + + /* If the mouse is not on this screen but used to be, that's motion. + If the mouse was not on this screen, but is now, that's motion. + */ + { + Bool on_screen_p = (this_poll_mouse->root_x != -1 && + this_poll_mouse->root_y != -1); + Bool was_on_screen_p = (last_poll_mouse->root_x != -1 && + last_poll_mouse->root_y != -1); + + if (on_screen_p != was_on_screen_p) + moved_p = True; + } + + if (p->debug_p && (distance != 0 || moved_p)) + { + fprintf (stderr, "%s: %s %d: pointer %s", blurb(), debug_type, debug_id, + (moved_p ? "moved: " : "ignored:")); + if (last_poll_mouse->root_x == -1) + fprintf (stderr, "off screen"); + else + fprintf (stderr, "%d,%d", + last_poll_mouse->root_x, + last_poll_mouse->root_y); + fprintf (stderr, " -> "); + if (this_poll_mouse->root_x == -1) + fprintf (stderr, "off screen"); + else + fprintf (stderr, "%d,%d", this_poll_mouse->root_x, + this_poll_mouse->root_y); + if (last_poll_mouse->root_x != -1 && this_poll_mouse->root_x != -1) + fprintf (stderr, " (%d,%d; %d/%lu=%d)", + ABS(last_poll_mouse->root_x - this_poll_mouse->root_x), + ABS(last_poll_mouse->root_y - this_poll_mouse->root_y), + distance, seconds, dps); + + fprintf (stderr, ".\n"); + } + + if (!moved_p && + mods_p && + this_poll_mouse->mask != last_poll_mouse->mask) + { + moved_p = True; + + if (p->debug_p) + fprintf (stderr, "%s: %s %d: modifiers changed: 0x%04x -> 0x%04x.\n", + blurb(), debug_type, debug_id, + last_poll_mouse->mask, this_poll_mouse->mask); + } + + last_poll_mouse->child = this_poll_mouse->child; + last_poll_mouse->mask = this_poll_mouse->mask; + + if (moved_p || seconds > 0) + { + last_poll_mouse->time = this_poll_mouse->time; + last_poll_mouse->root_x = this_poll_mouse->root_x; + last_poll_mouse->root_y = this_poll_mouse->root_y; + } + + return moved_p; +} + +/* Returns true if core mouse pointer has moved since the last time we checked. + */ +static Bool +pointer_moved_p (saver_screen_info *ssi, Bool mods_p) +{ + saver_info *si = ssi->global; + + Window root; + poll_mouse_data this_poll_mouse; + int x, y; + + /* don't check xinerama pseudo-screens. */ + if (!ssi->real_screen_p) return False; + + this_poll_mouse.time = time ((time_t *) 0); + + if (!XQueryPointer (si->dpy, ssi->screensaver_window, &root, + &this_poll_mouse.child, + &this_poll_mouse.root_x, &this_poll_mouse.root_y, + &x, &y, &this_poll_mouse.mask)) + { + /* If XQueryPointer() returns false, the mouse is not on this screen. + */ + this_poll_mouse.root_x = -1; + this_poll_mouse.root_y = -1; + this_poll_mouse.child = 0; + this_poll_mouse.mask = 0; + } + else + si->last_activity_screen = ssi; + + return device_pointer_moved_p(si, &(ssi->last_poll_mouse), &this_poll_mouse, + mods_p, "screen", ssi->number); +} + + +/* When we aren't using a server extension, this timer is used to periodically + wake up and poll the mouse position, which is possibly more reliable than + selecting motion events on every window. + */ +static void +check_pointer_timer (XtPointer closure, XtIntervalId *id) +{ + int i; + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + Bool active_p = False; + + if (!si->using_proc_interrupts && + (si->using_xidle_extension || + si->using_mit_saver_extension || + si->using_sgi_saver_extension)) + /* If an extension is in use, we should not be polling the mouse. + Unless we're also checking /proc/interrupts, in which case, we should. + */ + abort (); + + if (id && *id == si->check_pointer_timer_id) /* this is us - it's expired */ + si->check_pointer_timer_id = 0; + + if (si->check_pointer_timer_id) /* only queue one at a time */ + XtRemoveTimeOut (si->check_pointer_timer_id); + + si->check_pointer_timer_id = /* now re-queue */ + XtAppAddTimeOut (si->app, p->pointer_timeout, check_pointer_timer, + (XtPointer) si); + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (pointer_moved_p (ssi, True)) + active_p = True; + } + +#ifdef HAVE_PROC_INTERRUPTS + if (!active_p && + si->using_proc_interrupts && + proc_interrupts_activity_p (si)) + { + active_p = True; + } +#endif /* HAVE_PROC_INTERRUPTS */ + + if (active_p) + reset_timers (si); + + check_for_clock_skew (si); +} + + +/* An unfortunate situation is this: the saver is not active, because the + user has been typing. The machine is a laptop. The user closes the lid + and suspends it. The CPU halts. Some hours later, the user opens the + lid. At this point, Xt's timers will fire, and xscreensaver will blank + the screen. + + So far so good -- well, not really, but it's the best that we can do, + since the OS doesn't send us a signal *before* shutdown -- but if the + user had delayed locking (lockTimeout > 0) then we should start off + in the locked state, rather than only locking N minutes from when the + lid was opened. Also, eschewing fading is probably a good idea, to + clamp down as soon as possible. + + We only do this when we'd be polling the mouse position anyway. + This amounts to an assumption that machines with APM support also + have /proc/interrupts. + */ +static void +check_for_clock_skew (saver_info *si) +{ + saver_preferences *p = &si->prefs; + time_t now = time ((time_t *) 0); + long shift = now - si->last_wall_clock_time; + + if (p->debug_p) + { + int i = (si->last_wall_clock_time == 0 ? 0 : shift); + fprintf (stderr, + "%s: checking wall clock for hibernation (%d:%02d:%02d).\n", + blurb(), + (i / (60 * 60)), ((i / 60) % 60), (i % 60)); + } + + if (si->last_wall_clock_time != 0 && + shift > (p->timeout / 1000)) + { + if (p->verbose_p) + fprintf (stderr, "%s: wall clock has jumped by %ld:%02ld:%02ld%s\n", + blurb(), + (shift / (60 * 60)), ((shift / 60) % 60), (shift % 60), + (p->mode == DONT_BLANK ? " while saver disabled" : "")); + + /* If the saver is entirely disabled, there's no need to do the + emergency-blank-and-lock thing. + */ + if (p->mode != DONT_BLANK) + { + si->emergency_lock_p = True; + idle_timer ((XtPointer) si, 0); + } + } + + si->last_wall_clock_time = now; +} + + + +static void +dispatch_event (saver_info *si, XEvent *event) +{ + /* If this is for the splash dialog, pass it along. + Note that the password dialog is handled with its own event loop, + so events for that window will never come through here. + */ + if (si->splash_dialog && event->xany.window == si->splash_dialog) + handle_splash_event (si, event); + + XtDispatchEvent (event); +} + + +static void +swallow_unlock_typeahead_events (saver_info *si, XEvent *e) +{ + XEvent event; + char buf [100]; + int i = 0; + + memset (buf, 0, sizeof(buf)); + + event = *e; + + do + { + if (event.xany.type == KeyPress) + { + char s[2]; + int size = XLookupString ((XKeyEvent *) &event, s, 1, 0, 0); + if (size != 1) continue; + switch (*s) + { + case '\010': case '\177': /* Backspace */ + if (i > 0) i--; + break; + case '\025': case '\030': /* Erase line */ + case '\012': case '\015': /* Enter */ + case '\033': /* ESC */ + i = 0; + break; + case '\040': /* Space */ + if (i == 0) + break; /* ignore space at beginning of line */ + /* else, fall through */ + default: + buf [i++] = *s; + break; + } + } + + } while (i < sizeof(buf)-1 && + XCheckMaskEvent (si->dpy, KeyPressMask, &event)); + + buf[i] = 0; + + if (si->unlock_typeahead) + { + memset (si->unlock_typeahead, 0, strlen(si->unlock_typeahead)); + free (si->unlock_typeahead); + } + + if (i > 0) + si->unlock_typeahead = strdup (buf); + else + si->unlock_typeahead = 0; + + memset (buf, 0, sizeof(buf)); +} + + +/* methods of detecting idleness: + + explicitly informed by SGI SCREEN_SAVER server event; + explicitly informed by MIT-SCREEN-SAVER server event; + poll server idle time with XIDLE extension; + select events on all windows, and note absence of recent events; + note that /proc/interrupts has not changed in a while; + activated by clientmessage. + + methods of detecting non-idleness: + + read events on the xscreensaver window; + explicitly informed by SGI SCREEN_SAVER server event; + explicitly informed by MIT-SCREEN-SAVER server event; + select events on all windows, and note events on any of them; + note that /proc/interrupts has changed; + deactivated by clientmessage. + + I trust that explains why this function is a big hairy mess. + */ +void +sleep_until_idle (saver_info *si, Bool until_idle_p) +{ + saver_preferences *p = &si->prefs; + + /* We have to go through this union bullshit because gcc-4.4.0 has + stricter struct-aliasing rules. Without this, the optimizer + can fuck things up. + */ + union { + XEvent x_event; +# ifdef HAVE_RANDR + XRRScreenChangeNotifyEvent xrr_event; +# endif /* HAVE_RANDR */ +# ifdef HAVE_MIT_SAVER_EXTENSION + XScreenSaverNotifyEvent sevent; +# endif /* HAVE_MIT_SAVER_EXTENSION */ + } event; + + /* We need to select events on all windows if we're not using any extensions. + Otherwise, we don't need to. */ + Bool scanning_all_windows = !(si->using_xidle_extension || + si->using_mit_saver_extension || + si->using_sgi_saver_extension); + + /* We need to periodically wake up and check for idleness if we're not using + any extensions, or if we're using the XIDLE extension. The other two + extensions explicitly deliver events when we go idle/non-idle, so we + don't need to poll. */ + Bool polling_for_idleness = !(si->using_mit_saver_extension || + si->using_sgi_saver_extension); + + /* Whether we need to periodically wake up and check to see if the mouse has + moved. We only need to do this when not using any extensions. The reason + this isn't the same as `polling_for_idleness' is that the "idleness" poll + can happen (for example) 5 minutes from now, whereas the mouse-position + poll should happen with low periodicity. We don't need to poll the mouse + position with the XIDLE extension, but we do need to periodically wake up + and query the server with that extension. For our purposes, polling + /proc/interrupts is just like polling the mouse position. It has to + happen on the same kind of schedule. */ + Bool polling_mouse_position = (si->using_proc_interrupts || + !(si->using_xidle_extension || + si->using_mit_saver_extension || + si->using_sgi_saver_extension) || + si->using_xinput_extension); + + const char *why = 0; /* What caused the idle-state to change? */ + + if (until_idle_p) + { + if (polling_for_idleness) + /* This causes a no-op event to be delivered to us in a while, so that + we come back around through the event loop again. */ + schedule_wakeup_event (si, p->timeout, p->debug_p); + + if (polling_mouse_position) + /* Check to see if the mouse has moved, and set up a repeating timer + to do so periodically (typically, every 5 seconds.) */ + check_pointer_timer ((XtPointer) si, 0); + } + + while (1) + { + XtAppNextEvent (si->app, &event.x_event); + + switch (event.x_event.xany.type) { + case 0: /* our synthetic "timeout" event has been signalled */ + if (until_idle_p) + { + Time idle; + + /* We may be idle; check one last time to see if the mouse has + moved, just in case the idle-timer went off within the 5 second + window between mouse polling. If the mouse has moved, then + check_pointer_timer() will reset last_activity_time. + */ + if (polling_mouse_position) + check_pointer_timer ((XtPointer) si, 0); + +#ifdef HAVE_XIDLE_EXTENSION + if (si->using_xidle_extension) + { + /* The XIDLE extension uses the synthetic event to prod us into + re-asking the server how long the user has been idle. */ + if (! XGetIdleTime (si->dpy, &idle)) + { + fprintf (stderr, "%s: XGetIdleTime() failed.\n", blurb()); + saver_exit (si, 1, 0); + } + } + else +#endif /* HAVE_XIDLE_EXTENSION */ +#ifdef HAVE_MIT_SAVER_EXTENSION + if (si->using_mit_saver_extension) + { + /* We don't need to do anything in this case - the synthetic + event isn't necessary, as we get sent specific events + to wake us up. In fact, this event generally shouldn't + be being delivered when the MIT extension is in use. */ + idle = 0; + } + else +#endif /* HAVE_MIT_SAVER_EXTENSION */ +#ifdef HAVE_SGI_SAVER_EXTENSION + if (si->using_sgi_saver_extension) + { + /* We don't need to do anything in this case - the synthetic + event isn't necessary, as we get sent specific events + to wake us up. In fact, this event generally shouldn't + be being delivered when the SGI extension is in use. */ + idle = 0; + } + else +#endif /* HAVE_SGI_SAVER_EXTENSION */ + { + /* Otherwise, no server extension is in use. The synthetic + event was to tell us to wake up and see if the user is now + idle. Compute the amount of idle time by comparing the + `last_activity_time' to the wall clock. The l_a_t was set + by calling `reset_timers()', which is called only in only + two situations: when polling the mouse position has revealed + the the mouse has moved (user activity) or when we have read + an event (again, user activity.) + */ + idle = 1000 * (si->last_activity_time - time ((time_t *) 0)); + } + + if (idle >= p->timeout) + { + /* Look, we've been idle long enough. We're done. */ + why = "timeout"; + goto DONE; + } + else if (si->emergency_lock_p) + { + /* Oops, the wall clock has jumped far into the future, so + we need to lock down in a hurry! */ + why = "large wall clock change"; + goto DONE; + } + else + { + /* The event went off, but it turns out that the user has not + yet been idle for long enough. So re-signal the event. + Be economical: if we should blank after 5 minutes, and the + user has been idle for 2 minutes, then set this timer to + go off in 3 minutes. + */ + if (polling_for_idleness) + schedule_wakeup_event (si, p->timeout - idle, p->debug_p); + } + } + break; + + case ClientMessage: + if (handle_clientmessage (si, &event.x_event, until_idle_p)) + { + why = "ClientMessage"; + goto DONE; + } + break; + + case CreateNotify: + /* A window has been created on the screen somewhere. If we're + supposed to scan all windows for events, prepare this window. */ + if (scanning_all_windows) + { + Window w = event.x_event.xcreatewindow.window; + start_notice_events_timer (si, w, p->debug_p); + } + break; + + case KeyPress: + case ButtonPress: + /* Ignore release events so that hitting ESC at the password dialog + doesn't result in the password dialog coming right back again when + the fucking release key is seen! */ + /* case KeyRelease:*/ + /* case ButtonRelease:*/ + case MotionNotify: + + if (p->debug_p) + { + Window root=0, window=0; + int x=-1, y=-1; + const char *type = 0; + if (event.x_event.xany.type == MotionNotify) + { + /*type = "MotionNotify";*/ + root = event.x_event.xmotion.root; + window = event.x_event.xmotion.window; + x = event.x_event.xmotion.x_root; + y = event.x_event.xmotion.y_root; + } + else if (event.x_event.xany.type == KeyPress) + { + type = "KeyPress"; + root = event.x_event.xkey.root; + window = event.x_event.xkey.window; + x = y = -1; + } + else if (event.x_event.xany.type == ButtonPress) + { + type = "ButtonPress"; + root = event.x_event.xkey.root; + window = event.x_event.xkey.window; + x = event.x_event.xmotion.x_root; + y = event.x_event.xmotion.y_root; + } + + if (type) + { + int i; + for (i = 0; i < si->nscreens; i++) + if (root == RootWindowOfScreen (si->screens[i].screen)) + break; + fprintf (stderr,"%s: %d: %s on 0x%lx", + blurb(), i, type, (unsigned long) window); + + /* Be careful never to do this unless in -debug mode, as + this could expose characters from the unlock password. */ + if (p->debug_p && event.x_event.xany.type == KeyPress) + { + KeySym keysym; + char c = 0; + XLookupString (&event.x_event.xkey, &c, 1, &keysym, 0); + fprintf (stderr, " (%s%s)", + (event.x_event.xkey.send_event ? "synthetic " : ""), + XKeysymToString (keysym)); + } + + if (x == -1) + fprintf (stderr, "\n"); + else + fprintf (stderr, " at %d,%d.\n", x, y); + } + } + + /* If any widgets want to handle this event, let them. */ + dispatch_event (si, &event.x_event); + + + /* If we got a MotionNotify event, figure out what screen it + was on and poll the mouse there: if the mouse hasn't moved + far enough to count as "real" motion, then ignore this + event. + */ + if (event.x_event.xany.type == MotionNotify) + { + int i; + for (i = 0; i < si->nscreens; i++) + if (event.x_event.xmotion.root == + RootWindowOfScreen (si->screens[i].screen)) + break; + if (i < si->nscreens) + { + if (!pointer_moved_p (&si->screens[i], False)) + continue; + } + } + + + /* We got a user event. + If we're waiting for the user to become active, this is it. + If we're waiting until the user becomes idle, reset the timers + (since now we have longer to wait.) + */ + if (!until_idle_p) + { + if (si->demoing_p && + (event.x_event.xany.type == MotionNotify || + event.x_event.xany.type == KeyRelease)) + /* When we're demoing a single hack, mouse motion doesn't + cause deactivation. Only clicks and keypresses do. */ + ; + else + { + /* If we're not demoing, then any activity causes deactivation. + */ + why = (event.x_event.xany.type == MotionNotify ?"mouse motion": + event.x_event.xany.type == KeyPress?"keyboard activity": + event.x_event.xany.type == ButtonPress ? "mouse click" : + "unknown user activity"); + goto DONE; + } + } + else + reset_timers (si); + + break; + + default: + +#ifdef HAVE_MIT_SAVER_EXTENSION + if (event.x_event.type == si->mit_saver_ext_event_number) + { + /* This event's number is that of the MIT-SCREEN-SAVER server + extension. This extension has one event number, and the event + itself contains sub-codes that say what kind of event it was + (an "idle" or "not-idle" event.) + */ + if (event.sevent.state == ScreenSaverOn) + { + int i = 0; + if (p->verbose_p) + fprintf (stderr, "%s: MIT ScreenSaverOn event received.\n", + blurb()); + + /* Get the "real" server window(s) out of the way as soon + as possible. */ + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->server_mit_saver_window && + window_exists_p (si->dpy, + ssi->server_mit_saver_window)) + XUnmapWindow (si->dpy, ssi->server_mit_saver_window); + } + + if (event.sevent.kind != ScreenSaverExternal) + { + fprintf (stderr, + "%s: ScreenSaverOn event wasn't of type External!\n", + blurb()); + } + + if (until_idle_p) + { + why = "MIT ScreenSaverOn"; + goto DONE; + } + } + else if (event.sevent.state == ScreenSaverOff) + { + if (p->verbose_p) + fprintf (stderr, "%s: MIT ScreenSaverOff event received.\n", + blurb()); + if (!until_idle_p) + { + why = "MIT ScreenSaverOff"; + goto DONE; + } + } + else + fprintf (stderr, + "%s: unknown MIT-SCREEN-SAVER event %d received!\n", + blurb(), event.sevent.state); + } + else + +#endif /* HAVE_MIT_SAVER_EXTENSION */ + + +#ifdef HAVE_SGI_SAVER_EXTENSION + if (event.x_event.type == (si->sgi_saver_ext_event_number + ScreenSaverStart)) + { + /* The SGI SCREEN_SAVER server extension has two event numbers, + and this event matches the "idle" event. */ + if (p->verbose_p) + fprintf (stderr, "%s: SGI ScreenSaverStart event received.\n", + blurb()); + + if (until_idle_p) + { + why = "SGI ScreenSaverStart"; + goto DONE; + } + } + else if (event.x_event.type == (si->sgi_saver_ext_event_number + + ScreenSaverEnd)) + { + /* The SGI SCREEN_SAVER server extension has two event numbers, + and this event matches the "idle" event. */ + if (p->verbose_p) + fprintf (stderr, "%s: SGI ScreenSaverEnd event received.\n", + blurb()); + if (!until_idle_p) + { + why = "SGI ScreenSaverEnd"; + goto DONE; + } + } + else +#endif /* HAVE_SGI_SAVER_EXTENSION */ + +#ifdef HAVE_XINPUT + /* If we got a MotionNotify event, check to see if the mouse has + moved far enough to count as "real" motion, if not, then ignore + this event. + */ + if ((si->num_xinput_devices > 0) && + (event.x_event.type == si->xinput_DeviceMotionNotify)) + { + XDeviceMotionEvent *dme = (XDeviceMotionEvent *) &event; + poll_mouse_data *last_poll_mouse = NULL; + int d; + + for (d = 0; d < si->num_xinput_devices; d++) + { + if (si->xinput_devices[d].device->device_id == dme->deviceid) + { + last_poll_mouse = &(si->xinput_devices[d].last_poll_mouse); + break; + } + } + + if (last_poll_mouse) + { + poll_mouse_data this_poll_mouse; + this_poll_mouse.root_x = dme->x_root; + this_poll_mouse.root_y = dme->y_root; + this_poll_mouse.child = dme->subwindow; + this_poll_mouse.mask = dme->device_state; + this_poll_mouse.time = dme->time / 1000; /* milliseconds */ + + if (!device_pointer_moved_p (si, last_poll_mouse, + &this_poll_mouse, False, + "device", dme->deviceid)) + continue; + } + else if (p->debug_p) + fprintf (stderr, + "%s: received MotionNotify from unknown device %d\n", + blurb(), (int) dme->deviceid); + } + + if ((!until_idle_p) && + (si->num_xinput_devices > 0) && + (event.x_event.type == si->xinput_DeviceMotionNotify || + event.x_event.type == si->xinput_DeviceButtonPress)) + /* Ignore DeviceButtonRelease, see ButtonRelease comment above. */ + { + + dispatch_event (si, &event.x_event); + if (si->demoing_p && + event.x_event.type == si->xinput_DeviceMotionNotify) + /* When we're demoing a single hack, mouse motion doesn't + cause deactivation. Only clicks and keypresses do. */ + ; + else + /* If we're not demoing, then any activity causes deactivation. + */ + { + why = (event.x_event.type == si->xinput_DeviceMotionNotify + ? "XI mouse motion" : + event.x_event.type == si->xinput_DeviceButtonPress + ? "XI mouse click" : "unknown XINPUT event"); + goto DONE; + } + } + else +#endif /* HAVE_XINPUT */ + +#ifdef HAVE_RANDR + if (si->using_randr_extension && + (event.x_event.type == + (si->randr_event_number + RRScreenChangeNotify))) + { + /* The Resize and Rotate extension sends an event when the + size, rotation, or refresh rate of any screen has changed. + */ + if (p->verbose_p) + { + /* XRRRootToScreen is in Xrandr.h 1.4, 2001/06/07 */ + int screen = XRRRootToScreen (si->dpy, event.xrr_event.window); + fprintf (stderr, "%s: %d: screen change event received\n", + blurb(), screen); + } + +# ifdef RRScreenChangeNotifyMask + /* Inform Xlib that it's ok to update its data structures. */ + XRRUpdateConfiguration (&event.x_event); /* Xrandr.h 1.9, 2002/09/29 */ +# endif /* RRScreenChangeNotifyMask */ + + /* Resize the existing xscreensaver windows and cached ssi data. */ + if (update_screen_layout (si)) + { + if (p->verbose_p) + { + fprintf (stderr, "%s: new layout:\n", blurb()); + describe_monitor_layout (si); + } + resize_screensaver_window (si); + } + } + else +#endif /* HAVE_RANDR */ + + /* Just some random event. Let the Widgets handle it, if desired. */ + dispatch_event (si, &event.x_event); + } + } + DONE: + + if (p->verbose_p) + { + if (! why) why = "unknown reason"; + fprintf (stderr, "%s: %s (%s)\n", blurb(), + (until_idle_p ? "user is idle" : "user is active"), + why); + } + + /* If there's a user event on the queue, swallow it. + If we're using a server extension, and the user becomes active, we + get the extension event before the user event -- so the keypress or + motion or whatever is still on the queue. This makes "unfade" not + work, because it sees that event, and bugs out. (This problem + doesn't exhibit itself without an extension, because in that case, + there's only one event generated by user activity, not two.) + */ + if (!until_idle_p && si->locked_p) + swallow_unlock_typeahead_events (si, &event.x_event); + else + while (XCheckMaskEvent (si->dpy, + (KeyPressMask|ButtonPressMask|PointerMotionMask), + &event.x_event)) + ; + + + if (si->check_pointer_timer_id) + { + XtRemoveTimeOut (si->check_pointer_timer_id); + si->check_pointer_timer_id = 0; + } + if (si->timer_id) + { + XtRemoveTimeOut (si->timer_id); + si->timer_id = 0; + } + + if (until_idle_p && si->cycle_id) /* no cycle timer when inactive */ + abort (); +} + + + +/* Some crap for dealing with /proc/interrupts. + + On Linux systems, it's possible to see the hardware interrupt count + associated with the keyboard. We can therefore use that as another method + of detecting idleness. + + Why is it a good idea to do this? Because it lets us detect keyboard + activity that is not associated with X events. For example, if the user + has switched to another virtual console, it's good for xscreensaver to not + be running graphics hacks on the (non-visible) X display. The common + complaint that checking /proc/interrupts addresses is that the user is + playing Quake on a non-X console, and the GL hacks are perceptibly slowing + the game... + + This is tricky for a number of reasons. + + * First, we must be sure to only do this when running on an X server that + is on the local machine (because otherwise, we'd be reacting to the + wrong keyboard.) The way we do this is by noting that the $DISPLAY is + pointing to display 0 on the local machine. It *could* be that display + 1 is also on the local machine (e.g., two X servers, each on a different + virtual-terminal) but it's also possible that screen 1 is an X terminal, + using this machine as the host. So we can't take that chance. + + * Second, one can only access these interrupt numbers in a completely + and utterly brain-damaged way. You would think that one would use an + ioctl for this. But no. The ONLY way to get this information is to + open the pseudo-file /proc/interrupts AS A FILE, and read the numbers + out of it TEXTUALLY. Because this is Unix, and all the world's a file, + and the only real data type is the short-line sequence of ASCII bytes. + + Now it's all well and good that the /proc/interrupts pseudo-file + exists; that's a clever idea, and a useful API for things that are + already textually oriented, like shell scripts, and users doing + interactive debugging sessions. But to make a *C PROGRAM* open a file + and parse the textual representation of integers out of it is just + insane. + + * Third, you can't just hold the file open, and fseek() back to the + beginning to get updated data! If you do that, the data never changes. + And I don't want to call open() every five seconds, because I don't want + to risk going to disk for any inodes. It turns out that if you dup() + it early, then each copy gets fresh data, so we can get around that in + this way (but for how many releases, one might wonder?) + + * Fourth, the format of the output of the /proc/interrupts file is + undocumented, and has changed several times already! In Linux 2.0.33, + even on a multiprocessor machine, it looks like this: + + 0: 309453991 timer + 1: 4771729 keyboard + + but in Linux 2.2 and 2.4 kernels with MP machines, it looks like this: + + CPU0 CPU1 + 0: 1671450 1672618 IO-APIC-edge timer + 1: 13037 13495 IO-APIC-edge keyboard + + and in Linux 2.6, it's gotten even goofier: now there are two lines + labelled "i8042". One of them is the keyboard, and one of them is + the PS/2 mouse -- and of course, you can't tell them apart, except + by wiggling the mouse and noting which one changes: + + CPU0 CPU1 + 1: 32051 30864 IO-APIC-edge i8042 + 12: 476577 479913 IO-APIC-edge i8042 + + Joy! So how are we expected to parse that? Well, this code doesn't + parse it: it saves the first line with the string "keyboard" (or + "i8042") in it, and does a string-comparison to note when it has + changed. If there are two "i8042" lines, we assume the first is + the keyboard and the second is the mouse (doesn't matter which is + which, really, as long as we don't compare them against each other.) + + Thanks to Nat Friedman for figuring out most of this crap. + + Note that if you have a serial or USB mouse, or a USB keyboard, it won't + detect it. That's because there's no way to tell the difference between a + serial mouse and a general serial port, and all USB devices look the same + from here. It would be somewhat unfortunate to have the screensaver turn + off when the modem on COM1 burped, or when a USB disk was accessed. + */ + + +#ifdef HAVE_PROC_INTERRUPTS + +#define PROC_INTERRUPTS "/proc/interrupts" + +Bool +query_proc_interrupts_available (saver_info *si, const char **why) +{ + /* We can use /proc/interrupts if $DISPLAY points to :0, and if the + "/proc/interrupts" file exists and is readable. + */ + FILE *f; + if (why) *why = 0; + + if (!display_is_on_console_p (si)) + { + if (why) *why = "not on primary console"; + return False; + } + + f = fopen (PROC_INTERRUPTS, "r"); + if (!f) + { + if (why) *why = "does not exist"; + return False; + } + + fclose (f); + return True; +} + + +static Bool +proc_interrupts_activity_p (saver_info *si) +{ + static FILE *f0 = 0; + FILE *f1 = 0; + int fd; + static char last_kbd_line[255] = { 0, }; + static char last_ptr_line[255] = { 0, }; + char new_line[sizeof(last_kbd_line)]; + Bool checked_kbd = False, kbd_changed = False; + Bool checked_ptr = False, ptr_changed = False; + int i8042_count = 0; + + if (!f0) + { + /* First time -- open the file. */ + f0 = fopen (PROC_INTERRUPTS, "r"); + if (!f0) + { + char buf[255]; + sprintf(buf, "%s: error opening %s", blurb(), PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + +# if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) + /* Close this fd upon exec instead of inheriting / leaking it. */ + if (fcntl (fileno (f0), F_SETFD, FD_CLOEXEC) != 0) + perror ("fcntl: CLOEXEC:"); +# endif + } + + if (f0 == (FILE *) -1) /* means we got an error initializing. */ + return False; + + fd = dup (fileno (f0)); + if (fd < 0) + { + char buf[255]; + sprintf(buf, "%s: could not dup() the %s fd", blurb(), PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + + f1 = fdopen (fd, "r"); + if (!f1) + { + char buf[255]; + sprintf(buf, "%s: could not fdopen() the %s fd", blurb(), + PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + + /* Actually, I'm unclear on why this fseek() is necessary, given the timing + of the dup() above, but it is. */ + if (fseek (f1, 0, SEEK_SET) != 0) + { + char buf[255]; + sprintf(buf, "%s: error rewinding %s", blurb(), PROC_INTERRUPTS); + perror (buf); + goto FAIL; + } + + /* Now read through the pseudo-file until we find the "keyboard", + "PS/2 mouse", or "i8042" lines. */ + + while (fgets (new_line, sizeof(new_line)-1, f1)) + { + Bool i8042_p = !!strstr (new_line, "i8042"); + if (i8042_p) i8042_count++; + + if (strchr (new_line, ',')) + { + /* Ignore any line that has a comma on it: this is because + a setup like this: + + 12: 930935 XT-PIC usb-uhci, PS/2 Mouse + + is really bad news. It *looks* like we can note mouse + activity from that line, but really, that interrupt gets + fired any time any USB device has activity! So we have + to ignore any shared IRQs. + */ + } + else if (!checked_kbd && + (strstr (new_line, "keyboard") || + (i8042_p && i8042_count == 1))) + { + /* Assume the keyboard interrupt is the line that says "keyboard", + or the *first* line that says "i8042". + */ + kbd_changed = (*last_kbd_line && !!strcmp (new_line, last_kbd_line)); + strcpy (last_kbd_line, new_line); + checked_kbd = True; + } + else if (!checked_ptr && + (strstr (new_line, "PS/2 Mouse") || + (i8042_p && i8042_count == 2))) + { + /* Assume the mouse interrupt is the line that says "PS/2 mouse", + or the *second* line that says "i8042". + */ + ptr_changed = (*last_ptr_line && !!strcmp (new_line, last_ptr_line)); + strcpy (last_ptr_line, new_line); + checked_ptr = True; + } + + if (checked_kbd && checked_ptr) + break; + } + + if (checked_kbd || checked_ptr) + { + fclose (f1); + + if (si->prefs.debug_p && (kbd_changed || ptr_changed)) + fprintf (stderr, "%s: /proc/interrupts activity: %s\n", + blurb(), + ((kbd_changed && ptr_changed) ? "mouse and kbd" : + kbd_changed ? "kbd" : + ptr_changed ? "mouse" : "ERR")); + + return (kbd_changed || ptr_changed); + } + + + /* If we got here, we didn't find either a "keyboard" or a "PS/2 Mouse" + line in the file at all. */ + fprintf (stderr, "%s: no keyboard or mouse data in %s?\n", + blurb(), PROC_INTERRUPTS); + + FAIL: + if (f1) + fclose (f1); + + if (f0 && f0 != (FILE *) -1) + fclose (f0); + + f0 = (FILE *) -1; + return False; +} + +#endif /* HAVE_PROC_INTERRUPTS */ + + +/* This timer goes off every few minutes, whether the user is idle or not, + to try and clean up anything that has gone wrong. + + It calls disable_builtin_screensaver() so that if xset has been used, + or some other program (like xlock) has messed with the XSetScreenSaver() + settings, they will be set back to sensible values (if a server extension + is in use, messing with xlock can cause xscreensaver to never get a wakeup + event, and could cause monitor power-saving to occur, and all manner of + heinousness.) + + If the screen is currently blanked, it raises the window, in case some + other window has been mapped on top of it. + + If the screen is currently blanked, and there is no hack running, it + clears the window, in case there is an error message printed on it (we + don't want the error message to burn in.) + */ + +static void +watchdog_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + + disable_builtin_screensaver (si, False); + + /* If the DPMS settings on the server have changed, change them back to + what ~/.xscreensaver says they should be. */ + sync_server_dpms_settings (si->dpy, + (p->dpms_enabled_p && + p->mode != DONT_BLANK), + p->dpms_standby / 1000, + p->dpms_suspend / 1000, + p->dpms_off / 1000, + False); + + if (si->screen_blanked_p) + { + Bool running_p = screenhack_running_p (si); + + if (si->dbox_up_p) + { + if (si->prefs.debug_p) + fprintf (stderr, "%s: dialog box is up: not raising screen.\n", + blurb()); + } + else + { + if (si->prefs.debug_p) + fprintf (stderr, "%s: watchdog timer raising %sscreen.\n", + blurb(), (running_p ? "" : "and clearing ")); + + raise_window (si, True, True, running_p); + } + + if (screenhack_running_p (si) && + !monitor_powered_on_p (si)) + { + int i; + if (si->prefs.verbose_p) + fprintf (stderr, + "%s: X says monitor has powered down; " + "killing running hacks.\n", blurb()); + for (i = 0; i < si->nscreens; i++) + kill_screenhack (&si->screens[i]); + } + + /* Re-schedule this timer. The watchdog timer defaults to a bit less + than the hack cycle period, but is never longer than one hour. + */ + si->watchdog_id = 0; + reset_watchdog_timer (si, True); + } +} + + +void +reset_watchdog_timer (saver_info *si, Bool on_p) +{ + saver_preferences *p = &si->prefs; + + if (si->watchdog_id) + { + XtRemoveTimeOut (si->watchdog_id); + si->watchdog_id = 0; + } + + if (on_p && p->watchdog_timeout) + { + si->watchdog_id = XtAppAddTimeOut (si->app, p->watchdog_timeout, + watchdog_timer, (XtPointer) si); + + if (p->debug_p) + fprintf (stderr, "%s: restarting watchdog_timer (%ld, %ld)\n", + blurb(), p->watchdog_timeout, si->watchdog_id); + } +} + + +/* It's possible that a race condition could have led to the saver + window being unexpectedly still mapped. This can happen like so: + + - screen is blanked + - hack is launched + - that hack tries to grab a screen image (it does this by + first unmapping the saver window, then remapping it.) + - hack unmaps window + - hack waits + - user becomes active + - hack re-maps window (*) + - driver kills subprocess + - driver unmaps window (**) + + The race is that (*) might have been sent to the server before + the client process was killed, but, due to scheduling randomness, + might not have been received by the server until after (**). + In other words, (*) and (**) might happen out of order, meaning + the driver will unmap the window, and then after that, the + recently-dead client will re-map it. This leaves the user + locked out (it looks like a desktop, but it's not!) + + To avoid this: after un-blanking the screen, we launch a timer + that wakes up once a second for ten seconds, and makes damned + sure that the window is still unmapped. + */ + +void +de_race_timer (XtPointer closure, XtIntervalId *id) +{ + saver_info *si = (saver_info *) closure; + saver_preferences *p = &si->prefs; + int secs = 1; + + if (id == 0) /* if id is 0, this is the initialization call. */ + { + si->de_race_ticks = 10; + if (p->verbose_p) + fprintf (stderr, "%s: starting de-race timer (%d seconds.)\n", + blurb(), si->de_race_ticks); + } + else + { + int i; + XSync (si->dpy, False); + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + Window w = ssi->screensaver_window; + XWindowAttributes xgwa; + XGetWindowAttributes (si->dpy, w, &xgwa); + if (xgwa.map_state != IsUnmapped) + { + if (p->verbose_p) + fprintf (stderr, + "%s: %d: client race! emergency unmap 0x%lx.\n", + blurb(), i, (unsigned long) w); + XUnmapWindow (si->dpy, w); + } + else if (p->debug_p) + fprintf (stderr, "%s: %d: (de-race of 0x%lx is cool.)\n", + blurb(), i, (unsigned long) w); + } + XSync (si->dpy, False); + + si->de_race_ticks--; + } + + if (id && *id == si->de_race_id) + si->de_race_id = 0; + + if (si->de_race_id) abort(); + + if (si->de_race_ticks <= 0) + { + si->de_race_id = 0; + if (p->verbose_p) + fprintf (stderr, "%s: de-race completed.\n", blurb()); + } + else + { + si->de_race_id = XtAppAddTimeOut (si->app, secs * 1000, + de_race_timer, closure); + } +} diff --git a/driver/types.h b/driver/types.h new file mode 100644 index 00000000..3ab8506c --- /dev/null +++ b/driver/types.h @@ -0,0 +1,437 @@ +/* xscreensaver, Copyright (c) 1993-2011 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_TYPES_H__ +#define __XSCREENSAVER_TYPES_H__ + +typedef struct saver_info saver_info; + +typedef enum { + ul_read, /* reading input or ready to do so */ + ul_success, /* auth success, unlock */ + ul_fail, /* auth fail */ + ul_cancel, /* user cancelled auth (pw_cancel or pw_null) */ + ul_time, /* timed out */ + ul_finished /* user pressed enter */ +} unlock_state; + +typedef struct screenhack screenhack; +struct screenhack { + Bool enabled_p; + char *visual; + char *name; + char *command; +}; + +typedef enum { + RANDOM_HACKS, ONE_HACK, BLANK_ONLY, DONT_BLANK, RANDOM_HACKS_SAME +} saver_mode; + +typedef enum { + TEXT_DATE, TEXT_LITERAL, TEXT_FILE, TEXT_PROGRAM, TEXT_URL +} text_mode; + +struct auth_message; +struct auth_response; + +typedef int (*auth_conv_cb_t) ( + int num_msg, + const struct auth_message *msg, + struct auth_response **resp, + saver_info *si); + +typedef struct saver_preferences saver_preferences; +typedef struct saver_screen_info saver_screen_info; +typedef struct passwd_dialog_data passwd_dialog_data; +typedef struct splash_dialog_data splash_dialog_data; +typedef struct _monitor monitor; + +typedef struct poll_mouse_data poll_mouse_data; +struct poll_mouse_data { + int root_x; + int root_y; + Window child; + unsigned int mask; + time_t time; +}; + +#ifdef HAVE_XINPUT +/* XInputExtension device support */ +#include + +typedef struct xinput_dev_info xinput_dev_info; +struct xinput_dev_info { + XDevice *device; + XEventClass press, release, valuator; + poll_mouse_data last_poll_mouse; +}; +#endif + +/* This structure holds all the user-specified parameters, read from the + command line, the resource database, or entered through a dialog box. + */ +struct saver_preferences { + + XrmDatabase db; /* The resource database into which the + init file is merged, and out of which the + preferences are parsed. */ + + time_t init_file_date; /* The date (from stat()) of the .xscreensaver + file the last time this process read or + wrote it. */ + + Bool verbose_p; /* whether to print out lots of status info */ + Bool timestamp_p; /* whether to mark messages with a timestamp */ + Bool capture_stderr_p; /* whether to redirect stdout/stderr */ + Bool ignore_uninstalled_p; /* whether to avoid displaying or complaining + about hacks that are not on $PATH */ + Bool debug_p; /* pay no mind to the man behind the curtain */ + Bool xsync_p; /* whether XSynchronize has been called */ + + Bool lock_p; /* whether to lock as well as save */ + + Bool fade_p; /* whether to fade to black, if possible */ + Bool unfade_p; /* whether to fade from black, if possible */ + Time fade_seconds; /* how long that should take */ + int fade_ticks; /* how many ticks should be used */ + Bool splash_p; /* whether to do a splash screen at startup */ + + 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 + + screenhack **screenhacks; /* the programs to run */ + int screenhacks_count; + + saver_mode mode; /* hack-selection mode */ + int selected_hack; /* in one_hack mode, this is the one */ + + int nice_inferior; /* nice value for subprocs */ + int inferior_memory_limit; /* setrlimit(LIMIT_AS) value for subprocs */ + + Time initial_delay; /* how long to sleep after launch */ + Time splash_duration; /* how long the splash screen stays up */ + Time timeout; /* how much idle time before activation */ + Time lock_timeout; /* how long after activation locking starts */ + Time cycle; /* how long each hack should run */ + Time passwd_timeout; /* how much time before pw dialog goes down */ + Time pointer_timeout; /* how often to check mouse position */ + Time notice_events_timeout; /* how long after window creation to select */ + Time watchdog_timeout; /* how often to re-raise and re-blank screen */ + int pointer_hysteresis; /* mouse motions less than N/sec are ignored */ + + Bool dpms_enabled_p; /* Whether to power down the monitor */ + Bool dpms_quickoff_p; /* Whether to power down monitor immediately + in "Blank Only" mode */ + Time dpms_standby; /* how long until monitor goes black */ + Time dpms_suspend; /* how long until monitor power-saves */ + Time dpms_off; /* how long until monitor powers down */ + + Bool grab_desktop_p; /* These are not used by "xscreensaver" */ + Bool grab_video_p; /* itself: they are used by the external */ + Bool random_image_p; /* "xscreensaver-getimage" program, and set */ + char *image_directory; /* by the "xscreensaver-demo" configurator. */ + + text_mode tmode; /* How we generate text to display. */ + char *text_literal; /* used when tmode is TEXT_LITERAL. */ + char *text_file; /* used when tmode is TEXT_FILE. */ + char *text_program; /* used when tmode is TEXT_PROGRAM. */ + char *text_url; /* used when tmode is TEXT_URL. */ + + Bool use_xidle_extension; /* which extension to use, if possible */ + Bool use_mit_saver_extension; + Bool use_sgi_saver_extension; + Bool use_proc_interrupts; + Bool use_xinput_extension; + + Bool getviewport_full_of_lies_p; /* XFree86 bug #421 */ + + char *shell; /* where to find /bin/sh */ + + char *demo_command; /* How to enter demo mode. */ + char *prefs_command; /* How to edit preferences. */ + char *help_url; /* Where the help document resides. */ + char *load_url_command; /* How one loads URLs. */ + char *new_login_command; /* Command for the "New Login" button. */ +}; + +/* This structure holds all the data that applies to the program as a whole, + or to the non-screen-specific parts of the display connection. + + The saver_preferences structure (prefs.h) holds all the user-specified + parameters, read from the command line, the resource database, or entered + through a dialog box. + */ +struct saver_info { + char *version; + saver_preferences prefs; + + int nscreens; + int ssi_count; + saver_screen_info *screens; + saver_screen_info *default_screen; /* ...on which dialogs will appear. */ + monitor **monitor_layout; /* private to screens.c */ + Visual **best_gl_visuals; /* visuals for GL hacks on screen N */ + + /* ======================================================================= + global connection info + ======================================================================= */ + + XtAppContext app; + Display *dpy; + + /* ======================================================================= + server extension info + ======================================================================= */ + + Bool using_xidle_extension; /* which extension is being used. */ + Bool using_mit_saver_extension; /* Note that `p->use_*' is the *request*, */ + Bool using_sgi_saver_extension; /* and `si->using_*' is the *reality*. */ + Bool using_proc_interrupts; + +# ifdef HAVE_MIT_SAVER_EXTENSION + int mit_saver_ext_event_number; + int mit_saver_ext_error_number; +# endif +# ifdef HAVE_SGI_SAVER_EXTENSION + int sgi_saver_ext_event_number; + int sgi_saver_ext_error_number; +# endif +# ifdef HAVE_RANDR + int randr_event_number; + int randr_error_number; + Bool using_randr_extension; +# endif + + Bool using_xinput_extension; /* Note that `p->use_*' is the *request*, */ + /* and `si->using_*' is the *reality*. */ +#ifdef HAVE_XINPUT + int xinput_ext_event_number; /* may not be used */ + int xinput_ext_error_number; + int xinput_DeviceButtonPress; /* Extension device event codes. */ + int xinput_DeviceButtonRelease; /* Assigned by server at runtime */ + int xinput_DeviceMotionNotify; + xinput_dev_info *xinput_devices; + int num_xinput_devices; +# endif + + /* ======================================================================= + blanking + ======================================================================= */ + + Bool screen_blanked_p; /* Whether the saver is currently active. */ + Window mouse_grab_window; /* Window holding our mouse grab */ + Window keyboard_grab_window; /* Window holding our keyboard grab */ + int mouse_grab_screen; /* The screen number the mouse grab is on */ + int keyboard_grab_screen; /* The screen number the keyboard grab is on */ + Bool fading_possible_p; /* Whether fading to/from black is possible. */ + Bool throttled_p; /* Whether we should temporarily just blank + the screen, not run hacks. (Deprecated: + users should use "xset dpms force off" + instead.) */ + time_t blank_time; /* The time at which the screen was blanked + (if currently blanked) or unblanked (if + not blanked.) */ + + + /* ======================================================================= + locking and runtime privileges + ======================================================================= */ + + Bool locked_p; /* Whether the screen is currently locked. */ + Bool dbox_up_p; /* Whether the demo-mode or passwd dialogs + are currently visible */ + + Bool locking_disabled_p; /* Sometimes locking is impossible. */ + char *nolock_reason; /* This is why. */ + + char *orig_uid; /* What uid/gid we had at startup, before + discarding privileges. */ + char *uid_message; /* Any diagnostics from our attempt to + discard privileges (printed only in + -verbose mode.) */ + Bool dangerous_uid_p; /* Set to true if we're running as a user id + which is known to not be a normal, non- + privileged user. */ + + Window passwd_dialog; /* The password dialog, if it's up. */ + passwd_dialog_data *pw_data; /* Other info necessary to draw it. */ + + int unlock_failures; /* Counts failed login attempts while the + screen is locked. */ + + char *unlock_typeahead; /* If the screen is locked, and the user types + a character, we assume that it is the first + character of the password. It's stored here + for the password dialog to use to populate + itself. */ + + char *user; /* The user whose session is locked. */ + char *cached_passwd; /* Cached password, used to avoid multiple + prompts for password-only auth mechanisms.*/ + unlock_state unlock_state; + + auth_conv_cb_t unlock_cb; /* The function used to prompt for creds. */ + void (*auth_finished_cb) (saver_info *si); + /* Called when authentication has finished, + regardless of success or failure. + May be NULL. */ + + + /* ======================================================================= + demoing + ======================================================================= */ + + Bool demoing_p; /* Whether we are demoing a single hack + (without UI.) */ + + Window splash_dialog; /* The splash dialog, if its up. */ + splash_dialog_data *sp_data; /* Other info necessary to draw it. */ + + + /* ======================================================================= + timers + ======================================================================= */ + + XtIntervalId lock_id; /* Timer to implement `prefs.lock_timeout' */ + XtIntervalId cycle_id; /* Timer to implement `prefs.cycle' */ + XtIntervalId timer_id; /* Timer to implement `prefs.timeout' */ + XtIntervalId watchdog_id; /* Timer to implement `prefs.watchdog */ + XtIntervalId check_pointer_timer_id; /* `prefs.pointer_timeout' */ + + XtIntervalId de_race_id; /* Timer to make sure screen un-blanks */ + int de_race_ticks; + + time_t last_activity_time; /* Used only when no server exts. */ + time_t last_wall_clock_time; /* Used to detect laptop suspend. */ + saver_screen_info *last_activity_screen; + + Bool emergency_lock_p; /* Set when the wall clock has jumped + (presumably due to laptop suspend) and we + need to lock down right away instead of + waiting for the lock timer to go off. */ + + + /* ======================================================================= + remote control + ======================================================================= */ + + int selection_mode; /* Set to -1 if the NEXT ClientMessage has just + been received; set to -2 if PREV has just + been received; set to N if SELECT or DEMO N + has been received. (This is kind of nasty.) + */ + + /* ======================================================================= + subprocs + ======================================================================= */ + + XtIntervalId stderr_popup_timer; + +}; + +/* This structure holds all the data that applies to the screen-specific parts + of the display connection; if the display has multiple screens, there will + be one of these for each screen. + */ +struct saver_screen_info { + saver_info *global; + + int number; /* The internal ordinal of this screen, + counting Xinerama rectangles as separate + screens. */ + int real_screen_number; /* The number of the underlying X screen on + which this rectangle lies. */ + Screen *screen; /* The X screen in question. */ + + int x, y, width, height; /* The size and position of this rectangle + on its underlying X screen. */ + + Bool real_screen_p; /* This will be true of exactly one ssi per + X screen. */ + + Widget toplevel_shell; + + /* ======================================================================= + blanking + ======================================================================= */ + + Window screensaver_window; /* The window that will impersonate the root, + when the screensaver activates. Note that + the window stored here may change, as we + destroy and recreate it on different + visuals. */ + Colormap cmap; /* The colormap that goes with the window. */ + Bool install_cmap_p; /* Whether this screen should have its own + colormap installed, for whichever of several + reasons. This is definitive (even a false + value here overrides prefs->install_cmap_p.) + */ + Visual *current_visual; /* The visual of the window. */ + int current_depth; /* How deep the visual (and the window) are. */ + + Visual *default_visual; /* visual to use when none other specified */ + + Window real_vroot; /* The original virtual-root window. */ + Window real_vroot_value; /* What was in the __SWM_VROOT property. */ + + Cursor cursor; /* A blank cursor that goes with the + real root window. */ + unsigned long black_pixel; /* Black, allocated from `cmap'. */ + + int blank_vp_x, blank_vp_y; /* Where the virtual-scrolling viewport was + when the screen went blank. We need to + prevent the X server from letting the mouse + bump the edges to scroll while the screen + is locked, so we reset to this when it has + moved, and the lock dialog is up... */ + +# ifdef HAVE_MIT_SAVER_EXTENSION + Window server_mit_saver_window; +# endif + + + /* ======================================================================= + demoing + ======================================================================= */ + + Colormap demo_cmap; /* The colormap that goes with the dialogs: + this might be the same as `cmap' so care + must be taken not to free it while it's + still in use. */ + + /* ======================================================================= + timers + ======================================================================= */ + + poll_mouse_data last_poll_mouse; /* Used only when no server exts. */ + + /* ======================================================================= + subprocs + ======================================================================= */ + + int current_hack; /* Index into `prefs.screenhacks' */ + pid_t pid; + + int stderr_text_x; + int stderr_text_y; + int stderr_line_height; + XFontStruct *stderr_font; + GC stderr_gc; + Window stderr_overlay_window; /* Used if the server has overlay planes */ + Colormap stderr_cmap; +}; + + +#endif /* __XSCREENSAVER_TYPES_H__ */ diff --git a/driver/vms-getpwnam.c b/driver/vms-getpwnam.c new file mode 100644 index 00000000..ec0650c9 --- /dev/null +++ b/driver/vms-getpwnam.c @@ -0,0 +1,129 @@ +/* + * getpwnam(name) - retrieves a UAF entry + * + * Author: Patrick L. Mahan + * Location: TGV, Inc + * Date: 15-Nov-1991 + * + * Purpose: Provides emulation for the UNIX getpwname routine. + * + * Modification History + * + * Date | Who | Version | Reason + * ------------+-----------+---------------+--------------------------- + * 15-Nov-1991 | PLM | 1.0 | First Write + */ + +#define PASSWDROUTINES + +#include +#include +#include +#include +#include +#include +#include "vms-pwd.h" + +struct uic { + unsigned short uid; + unsigned short gid; +}; + +#define TEST(ptr, str) { if (ptr == NULL) { \ + fprintf(stderr, "getpwnam: memory allocation failure for \"%s\"\n", \ + str); \ + return ((struct passwd *)(NULL)); \ + } } + +struct passwd *getpwnam(name) +char *name; +{ + int istatus; + int UserNameLen; + int UserOwnerLen; + int UserDeviceLen; + int UserDirLen; + static char UserName[13]; + static char UserOwner[32]; + static char UserDevice[32]; + static char UserDir[64]; + char *cptr, *sptr; + unsigned long int UserPwd[2]; + unsigned short int UserSalt; + unsigned long int UserEncrypt; + struct uic UicValue; + struct passwd *entry; + + struct dsc$descriptor_s VMSNAME = + {strlen(name), DSC$K_DTYPE_T, DSC$K_CLASS_S, name}; + + struct itmlist3 { + unsigned short int length; + unsigned short int item; + unsigned long int addr; + unsigned long int retaddr; + } ItemList[] = { + {12, UAI$_USERNAME, (unsigned long)&UserName, (unsigned long)&UserNameLen}, + {8, UAI$_PWD, (unsigned long)&UserPwd, 0}, + {4, UAI$_UIC, (unsigned long)&UicValue, 0}, + {32, UAI$_OWNER, (unsigned long)&UserOwner, (unsigned long)&UserOwnerLen}, + {32, UAI$_DEFDEV, (unsigned long)&UserDevice, (unsigned long)&UserDeviceLen}, + {64, UAI$_DEFDIR, (unsigned long)&UserDir, (unsigned long)&UserDirLen}, + {2, UAI$_SALT, (unsigned long)&UserSalt, 0}, + {4, UAI$_ENCRYPT, (unsigned long)&UserEncrypt, 0}, + {0, 0, 0, 0} + }; + + UserNameLen = 0; + istatus = sys$getuai (0, 0, &VMSNAME, &ItemList, 0, 0, 0); + + if (!(istatus & 1)) { + fprintf (stderr, "getpwnam: unable to retrieve passwd entry for %s\n", + name); + fprintf (stderr, "getpwnam: vms error number is 0x%x\n", istatus); + return ((struct passwd *)NULL); + } + + entry = (struct passwd *) calloc (1, sizeof(struct passwd)); + TEST(entry, "PASSWD_ENTRY"); + + entry->pw_uid = UicValue.uid; + entry->pw_gid = UicValue.gid; + entry->pw_salt = UserSalt; + entry->pw_encrypt = UserEncrypt; + + sptr = UserName; + cptr = calloc (UserNameLen+1, sizeof(char)); + TEST(cptr, "USERNAME"); + strncpy (cptr, sptr, UserNameLen); + cptr[UserNameLen] = '\0'; + entry->pw_name = cptr; + + cptr = calloc(8, sizeof(char)); + TEST(cptr, "PASSWORD"); + memcpy(cptr, UserPwd, 8); + entry->pw_passwd = cptr; + + sptr = UserOwner; sptr++; + cptr = calloc ((int)UserOwner[0]+1, sizeof(char)); + TEST(cptr, "FULLNAME"); + strncpy (cptr, sptr, (int)UserOwner[0]); + cptr[(int)UserOwner[0]] = '\0'; + entry->pw_gecos = cptr; + + cptr = calloc ((int)UserDevice[0]+(int)UserDir[0]+1, sizeof(char)); + TEST(cptr, "HOME"); + sptr = UserDevice; sptr++; + strncpy (cptr, sptr, (int)UserDevice[0]); + sptr = UserDir; sptr++; + strncat (cptr, sptr, (int)UserDir[0]); + cptr[(int)UserDevice[0]+(int)UserDir[0]] = '\0'; + entry->pw_dir = cptr; + + cptr = calloc (strlen("SYS$SYSTEM:LOGINOUT.EXE")+1, sizeof(char)); + TEST(cptr,"SHELL"); + strcpy (cptr, "SYS$SYSTEM:LOGINOUT.EXE"); + entry->pw_shell = cptr; + + return (entry); +} diff --git a/driver/vms-hpwd.c b/driver/vms-hpwd.c new file mode 100644 index 00000000..707e3ea5 --- /dev/null +++ b/driver/vms-hpwd.c @@ -0,0 +1,75 @@ +/* + * VAX/VMS Password hashing routines: + * + * uses the System Service SYS$HASH_PASSWORD + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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. + * + */ + +#include +#include +#include +#include +/* + * Hashing routine + */ +hash_vms_password(output_buf,input_buf,input_length,username,encryption_type,salt) +char *output_buf; +char *input_buf; +int input_length; +char *username; +int encryption_type; +unsigned short salt; +{ + struct dsc$descriptor_s password; + struct dsc$descriptor_s user; + + /* + * Check the VMS Version. If this is V5.4 or later, then + * we can use the new system service SYS$HASH_PASSWORD. Else + * fail and return garbage. + */ + + static char VMS_Version[32]; + struct { + unsigned short int Size; + unsigned short int Code; + char *Buffer; + unsigned short int *Resultant_Size; + } Item_List[2]={32, SYI$_VERSION, VMS_Version, 0, 0, 0}; + struct {int Size; char *Ptr;} Descr1; + + /* + * Get the information + */ + sys$getsyiw(0,0,0,Item_List,0,0,0); + /* + * Call the old routine if this isn't V5.4 or later... + */ +#ifndef __DECC + if ((VMS_Version[1] < '5') || + ((VMS_Version[1] == '5') && (VMS_Version[3] < '4'))) { + printf("Unsupported OS version\n"); + return(1); + } +#endif /* !__DECC */ + /* + * Call the SYS$HASH_PASSWORD system service... + */ + password.dsc$b_dtype = DSC$K_DTYPE_T; + password.dsc$b_class = DSC$K_CLASS_S; + password.dsc$w_length = input_length; + password.dsc$a_pointer = input_buf; + user.dsc$b_dtype = DSC$K_DTYPE_T; + user.dsc$b_class = DSC$K_CLASS_S; + user.dsc$w_length = strlen(username); + user.dsc$a_pointer = username; + sys$hash_password (&password, encryption_type, salt, &user, output_buf); +} diff --git a/driver/vms-pwd.h b/driver/vms-pwd.h new file mode 100644 index 00000000..6cb73d3e --- /dev/null +++ b/driver/vms-pwd.h @@ -0,0 +1,48 @@ +/* @(#)pwd.h 1.7 89/08/24 SMI; from S5R2 1.1 */ + +#ifndef __pwd_h +#define __pwd_h + +#ifdef vax11c +#include +#else +#include +#endif /* vax11c */ + +#ifdef PASSWDROUTINES +#define EXTERN +#else +#define EXTERN extern +#endif /* PASSWDROUTINES */ + +struct passwd { + char *pw_name; + char *pw_passwd; + int pw_uid; + int pw_gid; + short pw_salt; + int pw_encrypt; + char *pw_age; + char *pw_comment; + char *pw_gecos; + char *pw_dir; + char *pw_shell; +}; + + +#ifndef _POSIX_SOURCE +extern struct passwd *getpwent(); + +struct comment { + char *c_dept; + char *c_name; + char *c_acct; + char *c_bin; +}; + +#endif + +EXTERN struct passwd *getpwuid(/* uid_t uid */); +EXTERN struct passwd *getpwnam(/* char *name */); + +#endif /* !__pwd_h */ diff --git a/driver/vms-validate.c b/driver/vms-validate.c new file mode 100644 index 00000000..8f7141d6 --- /dev/null +++ b/driver/vms-validate.c @@ -0,0 +1,75 @@ +/* + * validate a password for a user + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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. + */ + +/* + * Includes + */ +#include +#include +#include + +#include "vms-pwd.h" +int hash_vms_password(char *output_buf,char *input_buf,int input_length, + char *username,int encryption_type,unsigned short salt); + +/* + * + * Validate a VMS UserName/Password pair. + * + */ + +int validate_user(name,password) +char *name; +char *password; +{ + char password_buf[64]; + char username_buf[31]; + char encrypt_buf[8]; + register int i; + register char *cp,*cp1; + struct passwd *user_entry; + + /* + * Get the users UAF entry + */ + user_entry = getpwnam(name); + + /* + * If user_entry == NULL then we got a bad error + * return -1 to indicate a bad error + */ + if (user_entry == NULL) return (-1); + + /* + * Uppercase the password + */ + cp = password; + cp1 = password_buf; + while (*cp) + if (islower(*cp)) + *cp1++ = toupper(*cp++); + else + *cp1++ = *cp++; + /* + * Get the length of the password + */ + i = strlen(password); + /* + * Encrypt the password + */ + hash_vms_password(encrypt_buf,password_buf,i,user_entry->pw_name, + user_entry->pw_encrypt, user_entry->pw_salt); + if (memcmp(encrypt_buf,user_entry->pw_passwd,8) == 0) + return(1); + else return(0); +} + diff --git a/driver/vms_axp.opt b/driver/vms_axp.opt new file mode 100644 index 00000000..04d465df --- /dev/null +++ b/driver/vms_axp.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_AXP/LIB +SYS$SHARE:DECW$XMLIBSHR.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHR.EXE/SHARE +SYS$SHARE:DECW$XTSHR.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/vms_axp_12.opt b/driver/vms_axp_12.opt new file mode 100644 index 00000000..25dd1f18 --- /dev/null +++ b/driver/vms_axp_12.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_AXP/LIB +SYS$SHARE:DECW$XMLIBSHR12.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XTLIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/vms_decc.opt b/driver/vms_decc.opt new file mode 100644 index 00000000..65bec033 --- /dev/null +++ b/driver/vms_decc.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_DECC/LIB +SYS$SHARE:DECW$XMLIBSHR.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHR.EXE/SHARE +SYS$SHARE:DECW$XTSHR.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/vms_decc_12.opt b/driver/vms_decc_12.opt new file mode 100644 index 00000000..fdd9a802 --- /dev/null +++ b/driver/vms_decc_12.opt @@ -0,0 +1,5 @@ +[-.UTILS]UTILS.OLB_DECC/LIB +SYS$SHARE:DECW$XMLIBSHR12.EXE/SHARE +SYS$SHARE:DECW$XMULIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XTLIBSHRR5.EXE/SHARE +SYS$SHARE:DECW$XLIBSHR.EXE/SHARE diff --git a/driver/windows.c b/driver/windows.c new file mode 100644 index 00000000..2bdc146c --- /dev/null +++ b/driver/windows.c @@ -0,0 +1,2001 @@ +/* windows.c --- turning the screen black; dealing with visuals, virtual roots. + * xscreensaver, Copyright (c) 1991-2011 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef VMS +# include /* for getpid() */ +# include "vms-gtod.h" /* for gettimeofday() */ +#endif /* VMS */ + +#ifndef VMS +# include /* for getpwuid() */ +#else /* VMS */ +# include "vms-pwd.h" +#endif /* VMS */ + +#ifdef HAVE_UNAME +# include /* for uname() */ +#endif /* HAVE_UNAME */ + +#include +/* #include / * for CARD32 */ +#include +#include /* for XSetClassHint() */ +#include +#include /* for time() */ +#include /* for the signal names */ +#include +#include + +/* You might think that to store an array of 32-bit quantities onto a + server-side property, you would pass an array of 32-bit data quantities + into XChangeProperty(). You would be wrong. You have to use an array + of longs, even if long is 64 bits (using 32 of each 64.) + */ +typedef long PROP32; + +#ifdef HAVE_MIT_SAVER_EXTENSION +# include +#endif /* HAVE_MIT_SAVER_EXTENSION */ + +#ifdef HAVE_XF86VMODE +# include +#endif /* HAVE_XF86VMODE */ + +#ifdef HAVE_XINERAMA +# include +#endif /* HAVE_XINERAMA */ + +/* This file doesn't need the Xt headers, so stub these types out... */ +#undef XtPointer +#define XtAppContext void* +#define XrmDatabase void* +#define XtIntervalId void* +#define XtPointer void* +#define Widget void* + +#include "xscreensaver.h" +#include "visual.h" +#include "fade.h" + + +extern int kill (pid_t, int); /* signal() is in sys/signal.h... */ + +Atom XA_VROOT, XA_XSETROOT_ID, XA_ESETROOT_PMAP_ID, XA_XROOTPMAP_ID; +Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_ID; +Atom XA_SCREENSAVER_STATUS; + + +extern saver_info *global_si_kludge; /* I hate C so much... */ + +static void maybe_transfer_grabs (saver_screen_info *ssi, + Window old_w, Window new_w, int new_screen); + +#define ALL_POINTER_EVENTS \ + (ButtonPressMask | ButtonReleaseMask | EnterWindowMask | \ + LeaveWindowMask | PointerMotionMask | PointerMotionHintMask | \ + Button1MotionMask | Button2MotionMask | Button3MotionMask | \ + Button4MotionMask | Button5MotionMask | ButtonMotionMask) + + +static const char * +grab_string(int status) +{ + switch (status) + { + case GrabSuccess: return "GrabSuccess"; + case AlreadyGrabbed: return "AlreadyGrabbed"; + case GrabInvalidTime: return "GrabInvalidTime"; + case GrabNotViewable: return "GrabNotViewable"; + case GrabFrozen: return "GrabFrozen"; + default: + { + static char foo[255]; + sprintf(foo, "unknown status: %d", status); + return foo; + } + } +} + +static int +grab_kbd(saver_info *si, Window w, int screen_no) +{ + saver_preferences *p = &si->prefs; + int status = XGrabKeyboard (si->dpy, w, True, + /* I don't really understand Sync vs Async, + but these seem to work... */ + GrabModeSync, GrabModeAsync, + CurrentTime); + if (status == GrabSuccess) + { + si->keyboard_grab_window = w; + si->keyboard_grab_screen = screen_no; + } + + if (p->verbose_p) + fprintf(stderr, "%s: %d: grabbing keyboard on 0x%lx... %s.\n", + blurb(), screen_no, (unsigned long) w, grab_string(status)); + return status; +} + + +static int +grab_mouse (saver_info *si, Window w, Cursor cursor, int screen_no) +{ + saver_preferences *p = &si->prefs; + int status = XGrabPointer (si->dpy, w, True, ALL_POINTER_EVENTS, + GrabModeAsync, GrabModeAsync, w, + cursor, CurrentTime); + if (status == GrabSuccess) + { + si->mouse_grab_window = w; + si->mouse_grab_screen = screen_no; + } + + if (p->verbose_p) + fprintf(stderr, "%s: %d: grabbing mouse on 0x%lx... %s.\n", + blurb(), screen_no, (unsigned long) w, grab_string(status)); + return status; +} + + +static void +ungrab_kbd(saver_info *si) +{ + saver_preferences *p = &si->prefs; + XUngrabKeyboard(si->dpy, CurrentTime); + if (p->verbose_p) + fprintf(stderr, "%s: %d: ungrabbing keyboard (was 0x%lx).\n", + blurb(), si->keyboard_grab_screen, + (unsigned long) si->keyboard_grab_window); + si->keyboard_grab_window = 0; +} + + +static void +ungrab_mouse(saver_info *si) +{ + saver_preferences *p = &si->prefs; + XUngrabPointer(si->dpy, CurrentTime); + if (p->verbose_p) + fprintf(stderr, "%s: %d: ungrabbing mouse (was 0x%lx).\n", + blurb(), si->mouse_grab_screen, + (unsigned long) si->mouse_grab_window); + si->mouse_grab_window = 0; +} + + +/* Apparently there is this program called "rdesktop" which is a windows + terminal server client for Unix. It would seem that this program holds + the keyboard GRABBED the whole time it has focus! This is, of course, + completely idiotic: the whole point of grabbing is to get events when + you do *not* have focus, so grabbing *only when* you have focus is + completely redundant -- unless your goal is to make xscreensaver not + able to ever lock the screen when your program is running. + + If xscreensaver blanks while rdesktop still has a keyboard grab, then + when we try to prompt for the password, we won't get the characters: + they'll be typed into rdesktop. + + Perhaps rdesktop will release its keyboard grab if it loses focus? + What the hell, let's give it a try. If we fail to grab the keyboard + four times in a row, we forcibly set focus to "None" and try four + more times. (We don't touch focus unless we're already having a hard + time getting a grab.) + */ +static void +nuke_focus (saver_info *si, int screen_no) +{ + saver_preferences *p = &si->prefs; + Window focus = 0; + int rev = 0; + + XGetInputFocus (si->dpy, &focus, &rev); + + if (p->verbose_p) + { + char w[255], r[255]; + + if (focus == PointerRoot) strcpy (w, "PointerRoot"); + else if (focus == None) strcpy (w, "None"); + else sprintf (w, "0x%lx", (unsigned long) focus); + + if (rev == RevertToParent) strcpy (r, "RevertToParent"); + else if (rev == RevertToPointerRoot) strcpy (r, "RevertToPointerRoot"); + else if (rev == RevertToNone) strcpy (r, "RevertToNone"); + else sprintf (r, "0x%x", rev); + + fprintf (stderr, "%s: %d: removing focus from %s / %s.\n", + blurb(), screen_no, w, r); + } + + XSetInputFocus (si->dpy, None, RevertToNone, CurrentTime); + XSync (si->dpy, False); +} + + +static void +ungrab_keyboard_and_mouse (saver_info *si) +{ + ungrab_mouse (si); + ungrab_kbd (si); +} + + +static Bool +grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, + int screen_no) +{ + Status mstatus = 0, kstatus = 0; + int i; + int retries = 4; + Bool focus_fuckus = False; + + AGAIN: + + for (i = 0; i < retries; i++) + { + XSync (si->dpy, False); + kstatus = grab_kbd (si, window, screen_no); + if (kstatus == GrabSuccess) + break; + + /* else, wait a second and try to grab again. */ + sleep (1); + } + + if (kstatus != GrabSuccess) + { + fprintf (stderr, "%s: couldn't grab keyboard! (%s)\n", + blurb(), grab_string(kstatus)); + + if (! focus_fuckus) + { + focus_fuckus = True; + nuke_focus (si, screen_no); + goto AGAIN; + } + } + + for (i = 0; i < retries; i++) + { + XSync (si->dpy, False); + mstatus = grab_mouse (si, window, cursor, screen_no); + if (mstatus == GrabSuccess) + break; + + /* else, wait a second and try to grab again. */ + sleep (1); + } + + if (mstatus != GrabSuccess) + fprintf (stderr, "%s: couldn't grab pointer! (%s)\n", + blurb(), grab_string(mstatus)); + + + /* When should we allow blanking to proceed? The current theory + is that a keyboard grab is mandatory; a mouse grab is optional. + + - If we don't have a keyboard grab, then we won't be able to + read a password to unlock, so the kbd grab is mandatory. + (We can't conditionalize this on locked_p, because someone + might run "xscreensaver-command -lock" at any time.) + + - If we don't have a mouse grab, then we might not see mouse + clicks as a signal to unblank -- but we will still see kbd + activity, so that's not a disaster. + + It has been suggested that we should allow blanking if locking + is disabled, and we have a mouse grab but no keyboard grab + (that is: kstatus != GrabSuccess && + mstatus == GrabSuccess && + si->locking_disabled_p) + That would allow screen blanking (but not locking) while the gdm + login screen had the keyboard grabbed, but one would have to use + the mouse to unblank. Keyboard characters would go to the gdm + login field without unblanking. I have not made this change + because I'm not completely convinced it is a safe thing to do. + */ + + if (kstatus != GrabSuccess) /* Do not blank without a kbd grab. */ + { + /* If we didn't get both grabs, release the one we did get. */ + ungrab_keyboard_and_mouse (si); + return False; + } + + return True; /* Grab is good, go ahead and blank. */ +} + + +int +move_mouse_grab (saver_info *si, Window to, Cursor cursor, int to_screen_no) +{ + Window old = si->mouse_grab_window; + + if (old == 0) + return grab_mouse (si, to, cursor, to_screen_no); + else + { + saver_preferences *p = &si->prefs; + int status; + + XSync (si->dpy, False); + XGrabServer (si->dpy); /* ############ DANGER! */ + XSync (si->dpy, False); + + if (p->verbose_p) + fprintf(stderr, "%s: grabbing server...\n", blurb()); + + ungrab_mouse (si); + status = grab_mouse (si, to, cursor, to_screen_no); + + if (status != GrabSuccess) /* Augh! */ + { + sleep (1); /* Note dramatic evil of sleeping + with server grabbed. */ + XSync (si->dpy, False); + status = grab_mouse (si, to, cursor, to_screen_no); + } + + if (status != GrabSuccess) /* Augh! Try to get the old one back... */ + grab_mouse (si, old, cursor, to_screen_no); + + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + + if (p->verbose_p) + fprintf(stderr, "%s: ungrabbing server.\n", blurb()); + + return status; + } +} + + +/* Prints an error message to stderr and returns True if there is another + xscreensaver running already. Silently returns False otherwise. */ +Bool +ensure_no_screensaver_running (Display *dpy, Screen *screen) +{ + Bool status = 0; + int i; + Window root = RootWindowOfScreen (screen); + Window root2, parent, *kids; + unsigned int nkids; + XErrorHandler old_handler = XSetErrorHandler (BadWindow_ehandler); + + if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) + abort (); + if (root != root2) + abort (); + if (parent) + abort (); + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *version; + + if (XGetWindowProperty (dpy, kids[i], XA_SCREENSAVER_VERSION, 0, 1, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, &version) + == Success + && type != None) + { + unsigned char *id; + if (!XGetWindowProperty (dpy, kids[i], XA_SCREENSAVER_ID, 0, 512, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, &id) + == Success + || type == None) + id = (unsigned char *) "???"; + + fprintf (stderr, + "%s: already running on display %s (window 0x%x)\n from process %s.\n", + blurb(), DisplayString (dpy), (int) kids [i], + (char *) id); + status = True; + } + + else if (XGetWindowProperty (dpy, kids[i], XA_WM_COMMAND, 0, 128, + False, XA_STRING, &type, &format, &nitems, + &bytesafter, &version) + == Success + && type != None + && !strcmp ((char *) version, "gnome-screensaver")) + { + fprintf (stderr, + "%s: \"%s\" is already running on display %s (window 0x%x)\n", + blurb(), (char *) version, + DisplayString (dpy), (int) kids [i]); + status = True; + break; + } + } + + if (kids) XFree ((char *) kids); + XSync (dpy, False); + XSetErrorHandler (old_handler); + return status; +} + + + +/* Virtual-root hackery */ + +#ifdef _VROOT_H_ +ERROR! You must not include vroot.h in this file. +#endif + +static void +store_vroot_property (Display *dpy, Window win, Window value) +{ +#if 0 + if (p->verbose_p) + fprintf (stderr, + "%s: storing XA_VROOT = 0x%x (%s) = 0x%x (%s)\n", blurb(), + win, + (win == screensaver_window ? "ScreenSaver" : + (win == real_vroot ? "VRoot" : + (win == real_vroot_value ? "Vroot_value" : "???"))), + value, + (value == screensaver_window ? "ScreenSaver" : + (value == real_vroot ? "VRoot" : + (value == real_vroot_value ? "Vroot_value" : "???")))); +#endif + XChangeProperty (dpy, win, XA_VROOT, XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &value, 1); +} + +static void +remove_vroot_property (Display *dpy, Window win) +{ +#if 0 + if (p->verbose_p) + fprintf (stderr, "%s: removing XA_VROOT from 0x%x (%s)\n", blurb(), win, + (win == screensaver_window ? "ScreenSaver" : + (win == real_vroot ? "VRoot" : + (win == real_vroot_value ? "Vroot_value" : "???")))); +#endif + XDeleteProperty (dpy, win, XA_VROOT); +} + + +static Bool safe_XKillClient (Display *dpy, XID id); + +static void +kill_xsetroot_data_1 (Display *dpy, Window window, + Atom prop, const char *atom_name, + Bool verbose_p) +{ + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *dataP = 0; + + /* If the user has been using xv or xsetroot as a screensaver (to display + an image on the screensaver window, as a kind of slideshow) then the + pixmap and its associated color cells have been put in RetainPermanent + CloseDown mode. Since we're not destroying the xscreensaver window, + but merely unmapping it, we need to free these resources or those + colormap cells will stay allocated while the screensaver is off. (We + could just delete the screensaver window and recreate it later, but + that could cause other problems.) This code does an atomic read-and- + delete of the _XSETROOT_ID property, and if it held a pixmap, then we + cause the RetainPermanent resources of the client which created it + (and which no longer exists) to be freed. + + Update: it seems that Gnome and KDE do this same trick, but with the + properties "ESETROOT_PMAP_ID" and/or "_XROOTPMAP_ID" instead of + "_XSETROOT_ID". So, we'll kill those too. + */ + if (XGetWindowProperty (dpy, window, prop, 0, 1, + True, AnyPropertyType, &type, &format, &nitems, + &bytesafter, &dataP) + == Success + && type != None) + { + Pixmap *pixP = (Pixmap *) dataP; + if (pixP && *pixP && type == XA_PIXMAP && format == 32 && + nitems == 1 && bytesafter == 0) + { + if (verbose_p) + fprintf (stderr, "%s: destroying %s data (0x%lX).\n", + blurb(), atom_name, *pixP); + safe_XKillClient (dpy, *pixP); + } + else + fprintf (stderr, + "%s: deleted unrecognised %s property: \n" + "\t%lu, %lu; type: %lu, format: %d, " + "nitems: %lu, bytesafter %ld\n", + blurb(), atom_name, + (unsigned long) pixP, (pixP ? *pixP : 0), type, + format, nitems, bytesafter); + } +} + + +static void +kill_xsetroot_data (Display *dpy, Window w, Bool verbose_p) +{ + kill_xsetroot_data_1 (dpy, w, XA_XSETROOT_ID, "_XSETROOT_ID", verbose_p); + kill_xsetroot_data_1 (dpy, w, XA_ESETROOT_PMAP_ID, "ESETROOT_PMAP_ID", + verbose_p); + kill_xsetroot_data_1 (dpy, w, XA_XROOTPMAP_ID, "_XROOTPMAP_ID", verbose_p); +} + + +static void +save_real_vroot (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + Display *dpy = si->dpy; + Screen *screen = ssi->screen; + int i; + Window root = RootWindowOfScreen (screen); + Window root2, parent, *kids; + unsigned int nkids; + XErrorHandler old_handler; + + /* It's possible that a window might be deleted between our call to + XQueryTree() and our call to XGetWindowProperty(). Don't die if + that happens (but just ignore that window, it's not the one we're + interested in anyway.) + */ + XSync (dpy, False); + old_handler = XSetErrorHandler (BadWindow_ehandler); + XSync (dpy, False); + + ssi->real_vroot = 0; + ssi->real_vroot_value = 0; + if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) + abort (); + if (root != root2) + abort (); + if (parent) + abort (); + for (i = 0; i < nkids; i++) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *dataP = 0; + Window *vrootP; + int j; + + /* Skip this window if it is the xscreensaver window of any other + screen (this can happen in the Xinerama case.) + */ + for (j = 0; j < si->nscreens; j++) + { + saver_screen_info *ssi2 = &si->screens[j]; + if (kids[i] == ssi2->screensaver_window) + goto SKIP; + } + + if (XGetWindowProperty (dpy, kids[i], XA_VROOT, 0, 1, False, XA_WINDOW, + &type, &format, &nitems, &bytesafter, + &dataP) + != Success) + continue; + if (! dataP) + continue; + + vrootP = (Window *) dataP; + if (ssi->real_vroot) + { + if (*vrootP == ssi->screensaver_window) abort (); + fprintf (stderr, + "%s: more than one virtual root window found (0x%x and 0x%x).\n", + blurb(), (int) ssi->real_vroot, (int) kids [i]); + exit (1); + } + ssi->real_vroot = kids [i]; + ssi->real_vroot_value = *vrootP; + SKIP: + ; + } + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + if (ssi->real_vroot) + { + remove_vroot_property (si->dpy, ssi->real_vroot); + XSync (dpy, False); + } + + XFree ((char *) kids); +} + + +static Bool +restore_real_vroot_1 (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + if (p->verbose_p && ssi->real_vroot) + fprintf (stderr, + "%s: restoring __SWM_VROOT property on the real vroot (0x%lx).\n", + blurb(), (unsigned long) ssi->real_vroot); + if (ssi->screensaver_window) + remove_vroot_property (si->dpy, ssi->screensaver_window); + if (ssi->real_vroot) + { + store_vroot_property (si->dpy, ssi->real_vroot, ssi->real_vroot_value); + ssi->real_vroot = 0; + ssi->real_vroot_value = 0; + /* make sure the property change gets there before this process + terminates! We might be doing this because we have intercepted + SIGTERM or something. */ + XSync (si->dpy, False); + return True; + } + return False; +} + +Bool +restore_real_vroot (saver_info *si) +{ + int i; + Bool did_any = False; + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (restore_real_vroot_1 (ssi)) + did_any = True; + } + return did_any; +} + + +/* Signal hackery to ensure that the vroot doesn't get left in an + inconsistent state + */ + +const char * +signal_name(int signal) +{ + switch (signal) { + case SIGHUP: return "SIGHUP"; + case SIGINT: return "SIGINT"; + case SIGQUIT: return "SIGQUIT"; + case SIGILL: return "SIGILL"; + case SIGTRAP: return "SIGTRAP"; +#ifdef SIGABRT + case SIGABRT: return "SIGABRT"; +#endif + case SIGFPE: return "SIGFPE"; + case SIGKILL: return "SIGKILL"; + case SIGBUS: return "SIGBUS"; + case SIGSEGV: return "SIGSEGV"; + case SIGPIPE: return "SIGPIPE"; + case SIGALRM: return "SIGALRM"; + case SIGTERM: return "SIGTERM"; +#ifdef SIGSTOP + case SIGSTOP: return "SIGSTOP"; +#endif +#ifdef SIGCONT + case SIGCONT: return "SIGCONT"; +#endif +#ifdef SIGUSR1 + case SIGUSR1: return "SIGUSR1"; +#endif +#ifdef SIGUSR2 + case SIGUSR2: return "SIGUSR2"; +#endif +#ifdef SIGEMT + case SIGEMT: return "SIGEMT"; +#endif +#ifdef SIGSYS + case SIGSYS: return "SIGSYS"; +#endif +#ifdef SIGCHLD + case SIGCHLD: return "SIGCHLD"; +#endif +#ifdef SIGPWR + case SIGPWR: return "SIGPWR"; +#endif +#ifdef SIGWINCH + case SIGWINCH: return "SIGWINCH"; +#endif +#ifdef SIGURG + case SIGURG: return "SIGURG"; +#endif +#ifdef SIGIO + case SIGIO: return "SIGIO"; +#endif +#ifdef SIGVTALRM + case SIGVTALRM: return "SIGVTALRM"; +#endif +#ifdef SIGXCPU + case SIGXCPU: return "SIGXCPU"; +#endif +#ifdef SIGXFSZ + case SIGXFSZ: return "SIGXFSZ"; +#endif +#ifdef SIGDANGER + case SIGDANGER: return "SIGDANGER"; +#endif + default: + { + static char buf[50]; + sprintf(buf, "signal %d\n", signal); + return buf; + } + } +} + + + +static RETSIGTYPE +restore_real_vroot_handler (int sig) +{ + saver_info *si = global_si_kludge; /* I hate C so much... */ + + signal (sig, SIG_DFL); + if (restore_real_vroot (si)) + fprintf (real_stderr, "\n%s: %s intercepted, vroot restored.\n", + blurb(), signal_name(sig)); + kill (getpid (), sig); +} + +static void +catch_signal (saver_info *si, int sig, RETSIGTYPE (*handler) (int)) +{ +# ifdef HAVE_SIGACTION + + struct sigaction a; + a.sa_handler = handler; + sigemptyset (&a.sa_mask); + a.sa_flags = 0; + + /* On Linux 2.4.9 (at least) we need to tell the kernel to not mask delivery + of this signal from inside its handler, or else when we execvp() the + process again, it starts up with SIGHUP blocked, meaning that killing + it with -HUP only works *once*. You'd think that execvp() would reset + all the signal masks, but it doesn't. + */ +# if defined(SA_NOMASK) + a.sa_flags |= SA_NOMASK; +# elif defined(SA_NODEFER) + a.sa_flags |= SA_NODEFER; +# endif + + if (sigaction (sig, &a, 0) < 0) +# else /* !HAVE_SIGACTION */ + if (((long) signal (sig, handler)) == -1L) +# endif /* !HAVE_SIGACTION */ + { + char buf [255]; + sprintf (buf, "%s: couldn't catch %s", blurb(), signal_name(sig)); + perror (buf); + saver_exit (si, 1, 0); + } +} + +static RETSIGTYPE saver_sighup_handler (int sig); + +void +handle_signals (saver_info *si) +{ + catch_signal (si, SIGHUP, saver_sighup_handler); + + catch_signal (si, SIGINT, restore_real_vroot_handler); + catch_signal (si, SIGQUIT, restore_real_vroot_handler); + catch_signal (si, SIGILL, restore_real_vroot_handler); + catch_signal (si, SIGTRAP, restore_real_vroot_handler); +#ifdef SIGIOT + catch_signal (si, SIGIOT, restore_real_vroot_handler); +#endif + catch_signal (si, SIGABRT, restore_real_vroot_handler); +#ifdef SIGEMT + catch_signal (si, SIGEMT, restore_real_vroot_handler); +#endif + catch_signal (si, SIGFPE, restore_real_vroot_handler); + catch_signal (si, SIGBUS, restore_real_vroot_handler); + catch_signal (si, SIGSEGV, restore_real_vroot_handler); +#ifdef SIGSYS + catch_signal (si, SIGSYS, restore_real_vroot_handler); +#endif + catch_signal (si, SIGTERM, restore_real_vroot_handler); +#ifdef SIGXCPU + catch_signal (si, SIGXCPU, restore_real_vroot_handler); +#endif +#ifdef SIGXFSZ + catch_signal (si, SIGXFSZ, restore_real_vroot_handler); +#endif +#ifdef SIGDANGER + catch_signal (si, SIGDANGER, restore_real_vroot_handler); +#endif +} + + +static RETSIGTYPE +saver_sighup_handler (int sig) +{ + saver_info *si = global_si_kludge; /* I hate C so much... */ + + /* Re-establish SIGHUP handler */ + catch_signal (si, SIGHUP, saver_sighup_handler); + + fprintf (stderr, "%s: %s received: restarting...\n", + blurb(), signal_name(sig)); + + if (si->screen_blanked_p) + { + int i; + for (i = 0; i < si->nscreens; i++) + kill_screenhack (&si->screens[i]); + unblank_screen (si); + XSync (si->dpy, False); + } + + restart_process (si); /* Does not return */ + abort (); +} + + + +void +saver_exit (saver_info *si, int status, const char *dump_core_reason) +{ + saver_preferences *p = &si->prefs; + static Bool exiting = False; + Bool bugp; + Bool vrs; + + if (exiting) + exit(status); + + exiting = True; + + vrs = restore_real_vroot (si); + emergency_kill_subproc (si); + shutdown_stderr (si); + + if (p->verbose_p && vrs) + fprintf (real_stderr, "%s: old vroot restored.\n", blurb()); + + fflush(real_stdout); + +#ifdef VMS /* on VMS, 1 is the "normal" exit code instead of 0. */ + if (status == 0) status = 1; + else if (status == 1) status = -1; +#endif + + bugp = !!dump_core_reason; + + if (si->prefs.debug_p && !dump_core_reason) + dump_core_reason = "because of -debug"; + + if (dump_core_reason) + { + /* Note that the Linux man page for setuid() says If uid is + different from the old effective uid, the process will be + forbidden from leaving core dumps. + */ + char cwd[4096]; /* should really be PATH_MAX, but who cares. */ + cwd[0] = 0; + fprintf(real_stderr, "%s: dumping core (%s)\n", blurb(), + dump_core_reason); + + if (bugp) + fprintf(real_stderr, + "%s: see http://www.jwz.org/xscreensaver/bugs.html\n" + "\t\t\tfor bug reporting information.\n\n", + blurb()); + +# if defined(HAVE_GETCWD) + if (!getcwd (cwd, sizeof(cwd))) +# elif defined(HAVE_GETWD) + if (!getwd (cwd)) +# endif + strcpy(cwd, "unknown."); + + fprintf (real_stderr, "%s: current directory is %s\n", blurb(), cwd); + describe_uids (si, real_stderr); + + /* Do this to drop a core file, so that we can get a stack trace. */ + abort(); + } + + exit (status); +} + + +/* Managing the actual screensaver window */ + +Bool +window_exists_p (Display *dpy, Window window) +{ + XErrorHandler old_handler; + XWindowAttributes xgwa; + xgwa.screen = 0; + old_handler = XSetErrorHandler (BadWindow_ehandler); + XGetWindowAttributes (dpy, window, &xgwa); + XSync (dpy, False); + XSetErrorHandler (old_handler); + return (xgwa.screen != 0); +} + +static void +store_saver_id (saver_screen_info *ssi) +{ + XClassHint class_hints; + saver_info *si = ssi->global; + unsigned long pid = (unsigned long) getpid (); + char buf[20]; + struct passwd *p = getpwuid (getuid ()); + const char *name, *host; + char *id; + + /* First store the name and class on the window. + */ + class_hints.res_name = progname; + class_hints.res_class = progclass; + XSetClassHint (si->dpy, ssi->screensaver_window, &class_hints); + XStoreName (si->dpy, ssi->screensaver_window, "screensaver"); + + /* Then store the xscreensaver version number. + */ + XChangeProperty (si->dpy, ssi->screensaver_window, + XA_SCREENSAVER_VERSION, + XA_STRING, 8, PropModeReplace, + (unsigned char *) si->version, + strlen (si->version)); + + /* Now store the XSCREENSAVER_ID property, that says what user and host + xscreensaver is running as. + */ + + if (p && p->pw_name && *p->pw_name) + name = p->pw_name; + else if (p) + { + sprintf (buf, "%lu", (unsigned long) p->pw_uid); + name = buf; + } + else + name = "???"; + +# if defined(HAVE_UNAME) + { + struct utsname uts; + if (uname (&uts) < 0) + host = "???"; + else + host = uts.nodename; + } +# elif defined(VMS) + host = getenv("SYS$NODE"); +# else /* !HAVE_UNAME && !VMS */ + host = "???"; +# endif /* !HAVE_UNAME && !VMS */ + + id = (char *) malloc (strlen(name) + strlen(host) + 50); + sprintf (id, "%lu (%s@%s)", pid, name, host); + + XChangeProperty (si->dpy, ssi->screensaver_window, + XA_SCREENSAVER_ID, XA_STRING, + 8, PropModeReplace, + (unsigned char *) id, strlen (id)); + free (id); +} + + +void +store_saver_status (saver_info *si) +{ + PROP32 *status; + int size = si->nscreens + 2; + int i; + + status = (PROP32 *) calloc (size, sizeof(PROP32)); + + status[0] = (PROP32) (si->screen_blanked_p + ? (si->locked_p ? XA_LOCK : XA_BLANK) + : 0); + status[1] = (PROP32) si->blank_time; + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + status [2 + i] = ssi->current_hack + 1; + } + + XChangeProperty (si->dpy, + RootWindow (si->dpy, 0), /* always screen #0 */ + XA_SCREENSAVER_STATUS, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *) status, size); + free (status); +} + + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + + +/* Returns True if successful, False if an X error occurred. + We need this because other programs might have done things to + our window that will cause XChangeWindowAttributes() to fail: + if that happens, we give up, destroy the window, and re-create + it. + */ +static Bool +safe_XChangeWindowAttributes (Display *dpy, Window window, + unsigned long mask, + XSetWindowAttributes *attrs) +{ + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + XChangeWindowAttributes (dpy, window, mask, attrs); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (!error_handler_hit_p); +} + + +/* This might not be necessary, but just in case. */ +static Bool +safe_XConfigureWindow (Display *dpy, Window window, + unsigned long mask, XWindowChanges *changes) +{ + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + XConfigureWindow (dpy, window, mask, changes); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (!error_handler_hit_p); +} + +/* This might not be necessary, but just in case. */ +static Bool +safe_XDestroyWindow (Display *dpy, Window window) +{ + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + XDestroyWindow (dpy, window); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (!error_handler_hit_p); +} + + +static Bool +safe_XKillClient (Display *dpy, XID id) +{ + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + XKillClient (dpy, id); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (!error_handler_hit_p); +} + + +#ifdef HAVE_XF86VMODE +Bool +safe_XF86VidModeGetViewPort (Display *dpy, int screen, int *xP, int *yP) +{ + Bool result; + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + result = XF86VidModeGetViewPort (dpy, screen, xP, yP); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (error_handler_hit_p + ? False + : result); +} + +/* There is no "safe_XF86VidModeGetModeLine" because it fails with an + untrappable I/O error instead of an X error -- so one must call + safe_XF86VidModeGetViewPort first, and assume that both have the + same error condition. Thank you XFree, may I have another. + */ + +#endif /* HAVE_XF86VMODE */ + + +static void +initialize_screensaver_window_1 (saver_screen_info *ssi) +{ + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + Bool install_cmap_p = ssi->install_cmap_p; /* not p->install_cmap_p */ + + /* This resets the screensaver window as fully as possible, since there's + no way of knowing what some random client may have done to us in the + meantime. We could just destroy and recreate the window, but that has + its own set of problems... + */ + XColor black; + XSetWindowAttributes attrs; + unsigned long attrmask; + static Bool printed_visual_info = False; /* only print the message once. */ + Window horked_window = 0; + + black.red = black.green = black.blue = 0; + + if (ssi->cmap == DefaultColormapOfScreen (ssi->screen)) + ssi->cmap = 0; + + if (ssi->current_visual != DefaultVisualOfScreen (ssi->screen)) + /* It's not the default visual, so we have no choice but to install. */ + install_cmap_p = True; + + if (install_cmap_p) + { + if (! ssi->cmap) + { + ssi->cmap = XCreateColormap (si->dpy, + RootWindowOfScreen (ssi->screen), + ssi->current_visual, AllocNone); + if (! XAllocColor (si->dpy, ssi->cmap, &black)) abort (); + ssi->black_pixel = black.pixel; + } + } + else + { + Colormap def_cmap = DefaultColormapOfScreen (ssi->screen); + if (ssi->cmap) + { + XFreeColors (si->dpy, ssi->cmap, &ssi->black_pixel, 1, 0); + if (ssi->cmap != ssi->demo_cmap && + ssi->cmap != def_cmap) + XFreeColormap (si->dpy, ssi->cmap); + } + ssi->cmap = def_cmap; + ssi->black_pixel = BlackPixelOfScreen (ssi->screen); + } + + attrmask = (CWOverrideRedirect | CWEventMask | CWBackingStore | CWColormap | + CWBackPixel | CWBackingPixel | CWBorderPixel); + attrs.override_redirect = True; + + /* When use_mit_saver_extension or use_sgi_saver_extension is true, we won't + actually be reading these events during normal operation; but we still + need to see Button events for demo-mode to work properly. + */ + attrs.event_mask = (KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask); + + attrs.backing_store = NotUseful; + attrs.colormap = ssi->cmap; + attrs.background_pixel = ssi->black_pixel; + attrs.backing_pixel = ssi->black_pixel; + attrs.border_pixel = ssi->black_pixel; + + if (!p->verbose_p || printed_visual_info) + ; + else if (ssi->current_visual == DefaultVisualOfScreen (ssi->screen)) + { + fprintf (stderr, "%s: %d: visual ", blurb(), ssi->number); + describe_visual (stderr, ssi->screen, ssi->current_visual, + install_cmap_p); + } + else + { + fprintf (stderr, "%s: using visual: ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + install_cmap_p); + fprintf (stderr, "%s: default visual: ", blurb()); + describe_visual (stderr, ssi->screen, + DefaultVisualOfScreen (ssi->screen), + ssi->install_cmap_p); + } + printed_visual_info = True; + +#ifdef HAVE_MIT_SAVER_EXTENSION + if (si->using_mit_saver_extension) + { + XScreenSaverInfo *info; + Window root = RootWindowOfScreen (ssi->screen); + +#if 0 + /* This call sets the server screensaver timeouts to what we think + they should be (based on the resources and args xscreensaver was + started with.) It's important that we do this to sync back up + with the server - if we have turned on prematurely, as by an + ACTIVATE ClientMessage, then the server may decide to activate + the screensaver while it's already active. That's ok for us, + since we would know to ignore that ScreenSaverActivate event, + but a side effect of this would be that the server would map its + saver window (which we then hide again right away) meaning that + the bits currently on the screen get blown away. Ugly. */ + + /* #### Ok, that doesn't work - when we tell the server that the + screensaver is "off" it sends us a Deactivate event, which is + sensible... but causes the saver to never come on. Hmm. */ + disable_builtin_screensaver (si, True); +#endif /* 0 */ + +#if 0 + /* #### The MIT-SCREEN-SAVER extension gives us access to the + window that the server itself uses for saving the screen. + However, using this window in any way, in particular, calling + XScreenSaverSetAttributes() as below, tends to make the X server + crash. So fuck it, let's try and get along without using it... + + It's also inconvenient to use this window because it doesn't + always exist (though the ID is constant.) So to use this + window, we'd have to reimplement the ACTIVATE ClientMessage to + tell the *server* to tell *us* to turn on, to cause the window + to get created at the right time. Gag. */ + XScreenSaverSetAttributes (si->dpy, root, + 0, 0, width, height, 0, + current_depth, InputOutput, visual, + attrmask, &attrs); + XSync (si->dpy, False); +#endif /* 0 */ + + info = XScreenSaverAllocInfo (); + XScreenSaverQueryInfo (si->dpy, root, info); + ssi->server_mit_saver_window = info->window; + if (! ssi->server_mit_saver_window) abort (); + XFree (info); + } +#endif /* HAVE_MIT_SAVER_EXTENSION */ + + if (ssi->screensaver_window) + { + XWindowChanges changes; + unsigned int changesmask = CWX|CWY|CWWidth|CWHeight|CWBorderWidth; + changes.x = ssi->x; + changes.y = ssi->y; + changes.width = ssi->width; + changes.height = ssi->height; + changes.border_width = 0; + + if (! (safe_XConfigureWindow (si->dpy, ssi->screensaver_window, + changesmask, &changes) && + safe_XChangeWindowAttributes (si->dpy, ssi->screensaver_window, + attrmask, &attrs))) + { + horked_window = ssi->screensaver_window; + ssi->screensaver_window = 0; + } + } + + if (!ssi->screensaver_window) + { + ssi->screensaver_window = + XCreateWindow (si->dpy, RootWindowOfScreen (ssi->screen), + ssi->x, ssi->y, ssi->width, ssi->height, + 0, ssi->current_depth, InputOutput, + ssi->current_visual, attrmask, &attrs); + reset_stderr (ssi); + + if (horked_window) + { + fprintf (stderr, + "%s: someone horked our saver window (0x%lx)! Recreating it...\n", + blurb(), (unsigned long) horked_window); + maybe_transfer_grabs (ssi, horked_window, ssi->screensaver_window, + ssi->number); + safe_XDestroyWindow (si->dpy, horked_window); + horked_window = 0; + } + + if (p->verbose_p) + fprintf (stderr, "%s: %d: saver window is 0x%lx.\n", + blurb(), ssi->number, + (unsigned long) ssi->screensaver_window); + } + + store_saver_id (ssi); /* store window name and IDs */ + + if (!ssi->cursor) + { + Pixmap bit; + bit = XCreatePixmapFromBitmapData (si->dpy, ssi->screensaver_window, + "\000", 1, 1, + BlackPixelOfScreen (ssi->screen), + BlackPixelOfScreen (ssi->screen), + 1); + ssi->cursor = XCreatePixmapCursor (si->dpy, bit, bit, &black, &black, + 0, 0); + XFreePixmap (si->dpy, bit); + } + + XSetWindowBackground (si->dpy, ssi->screensaver_window, ssi->black_pixel); + + if (si->demoing_p) + XUndefineCursor (si->dpy, ssi->screensaver_window); + else + XDefineCursor (si->dpy, ssi->screensaver_window, ssi->cursor); +} + +void +initialize_screensaver_window (saver_info *si) +{ + int i; + for (i = 0; i < si->nscreens; i++) + initialize_screensaver_window_1 (&si->screens[i]); +} + + +/* Called when the RANDR (Resize and Rotate) extension tells us that + the size of the screen has changed while the screen was blanked. + Call update_screen_layout() first, then call this to synchronize + the size of the saver windows to the new sizes of the screens. + */ +void +resize_screensaver_window (saver_info *si) +{ + saver_preferences *p = &si->prefs; + int i; + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + XWindowAttributes xgwa; + + /* Make sure a window exists -- it might not if a monitor was just + added for the first time. + */ + if (! ssi->screensaver_window) + { + initialize_screensaver_window_1 (ssi); + if (p->verbose_p) + fprintf (stderr, + "%s: %d: newly added window 0x%lx %dx%d+%d+%d\n", + blurb(), i, (unsigned long) ssi->screensaver_window, + ssi->width, ssi->height, ssi->x, ssi->y); + } + + /* Make sure the window is the right size -- it might not be if + the monitor changed resolution, or if a badly-behaved hack + screwed with it. + */ + XGetWindowAttributes (si->dpy, ssi->screensaver_window, &xgwa); + if (xgwa.x != ssi->x || + xgwa.y != ssi->y || + xgwa.width != ssi->width || + xgwa.height != ssi->height) + { + XWindowChanges changes; + unsigned int changesmask = CWX|CWY|CWWidth|CWHeight|CWBorderWidth; + changes.x = ssi->x; + changes.y = ssi->y; + changes.width = ssi->width; + changes.height = ssi->height; + changes.border_width = 0; + + if (p->verbose_p) + fprintf (stderr, + "%s: %d: resize 0x%lx from %dx%d+%d+%d to %dx%d+%d+%d\n", + blurb(), i, (unsigned long) ssi->screensaver_window, + xgwa.width, xgwa.height, xgwa.x, xgwa.y, + ssi->width, ssi->height, ssi->x, ssi->y); + + if (! safe_XConfigureWindow (si->dpy, ssi->screensaver_window, + changesmask, &changes)) + fprintf (stderr, "%s: %d: someone horked our saver window" + " (0x%lx)! Unable to resize it!\n", + blurb(), i, (unsigned long) ssi->screensaver_window); + } + + /* Now (if blanked) make sure that it's mapped and running a hack -- + it might not be if we just added it. (We also might be re-using + an old window that existed for a previous monitor that was + removed and re-added.) + + Note that spawn_screenhack() calls select_visual() which may destroy + and re-create the window via initialize_screensaver_window_1(). + */ + if (si->screen_blanked_p) + { + if (ssi->cmap) + XInstallColormap (si->dpy, ssi->cmap); + XMapRaised (si->dpy, ssi->screensaver_window); + if (! ssi->pid) + spawn_screenhack (ssi); + + /* Make sure the act of adding a screen doesn't present as + pointer motion (and thus cause an unblank). */ + { + Window root, child; + int x, y; + unsigned int mask; + XQueryPointer (si->dpy, ssi->screensaver_window, &root, &child, + &ssi->last_poll_mouse.root_x, + &ssi->last_poll_mouse.root_y, + &x, &y, &mask); + } + } + } + + /* Kill off any savers running on no-longer-extant monitors. + */ + for (; i < si->ssi_count; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->pid) + kill_screenhack (ssi); + if (ssi->screensaver_window) + { + XUnmapWindow (si->dpy, ssi->screensaver_window); + restore_real_vroot_1 (ssi); + } + } +} + + +void +raise_window (saver_info *si, + Bool inhibit_fade, Bool between_hacks_p, Bool dont_clear) +{ + saver_preferences *p = &si->prefs; + int i; + + if (si->demoing_p) + inhibit_fade = True; + + if (si->emergency_lock_p) + inhibit_fade = True; + + if (!dont_clear) + initialize_screensaver_window (si); + + reset_watchdog_timer (si, True); + + if (p->fade_p && si->fading_possible_p && !inhibit_fade) + { + Window *current_windows = (Window *) + calloc(sizeof(Window), si->nscreens); + Colormap *current_maps = (Colormap *) + calloc(sizeof(Colormap), si->nscreens); + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + current_windows[i] = ssi->screensaver_window; + current_maps[i] = (between_hacks_p + ? ssi->cmap + : DefaultColormapOfScreen (ssi->screen)); + /* Ensure that the default background of the window is really black, + not a pixmap or something. (This does not clear the window.) */ + XSetWindowBackground (si->dpy, ssi->screensaver_window, + ssi->black_pixel); + } + + if (p->verbose_p) fprintf (stderr, "%s: fading...\n", blurb()); + + XGrabServer (si->dpy); /* ############ DANGER! */ + + /* Clear the stderr layer on each screen. + */ + if (!dont_clear) + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->stderr_overlay_window) + /* Do this before the fade, since the stderr cmap won't fade + even if we uninstall it (beats me...) */ + clear_stderr (ssi); + } + + /* Note! The server is grabbed, and this will take several seconds + to complete! */ + fade_screens (si->dpy, current_maps, + current_windows, si->nscreens, + p->fade_seconds/1000, p->fade_ticks, True, !dont_clear); + + free(current_maps); + free(current_windows); + current_maps = 0; + current_windows = 0; + + if (p->verbose_p) fprintf (stderr, "%s: fading done.\n", blurb()); + +#ifdef HAVE_MIT_SAVER_EXTENSION + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->server_mit_saver_window && + window_exists_p (si->dpy, ssi->server_mit_saver_window)) + XUnmapWindow (si->dpy, ssi->server_mit_saver_window); + } +#endif /* HAVE_MIT_SAVER_EXTENSION */ + + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + } + else + { + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (!dont_clear) + XClearWindow (si->dpy, ssi->screensaver_window); + if (!dont_clear || ssi->stderr_overlay_window) + clear_stderr (ssi); + XMapRaised (si->dpy, ssi->screensaver_window); +#ifdef HAVE_MIT_SAVER_EXTENSION + if (ssi->server_mit_saver_window && + window_exists_p (si->dpy, ssi->server_mit_saver_window)) + XUnmapWindow (si->dpy, ssi->server_mit_saver_window); +#endif /* HAVE_MIT_SAVER_EXTENSION */ + } + } + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->cmap) + XInstallColormap (si->dpy, ssi->cmap); + } +} + + +int +mouse_screen (saver_info *si) +{ + saver_preferences *p = &si->prefs; + Window pointer_root, pointer_child; + int root_x, root_y, win_x, win_y; + unsigned int mask; + int i; + + if (si->nscreens == 1) + return 0; + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (XQueryPointer (si->dpy, RootWindowOfScreen (ssi->screen), + &pointer_root, &pointer_child, + &root_x, &root_y, &win_x, &win_y, &mask) && + root_x >= ssi->x && + root_y >= ssi->y && + root_x < ssi->x + ssi->width && + root_y < ssi->y + ssi->height) + { + if (p->verbose_p) + fprintf (stderr, "%s: mouse is on screen %d of %d\n", + blurb(), i, si->nscreens); + return i; + } + } + + /* couldn't figure out where the mouse is? Oh well. */ + return 0; +} + + +Bool +blank_screen (saver_info *si) +{ + int i; + Bool ok; + Window w; + int mscreen; + + /* Note: we do our grabs on the root window, not on the screensaver window. + If we grabbed on the saver window, then the demo mode and lock dialog + boxes wouldn't get any events. + + By "the root window", we mean "the root window that contains the mouse." + We use to always grab the mouse on screen 0, but that has the effect of + moving the mouse to screen 0 from whichever screen it was on, on + multi-head systems. + */ + mscreen = mouse_screen (si); + w = RootWindowOfScreen(si->screens[mscreen].screen); + ok = grab_keyboard_and_mouse (si, w, + (si->demoing_p ? 0 : si->screens[0].cursor), + mscreen); + + +# if 0 + if (si->using_mit_saver_extension || si->using_sgi_saver_extension) + /* If we're using a server extension, then failure to get a grab is + not a big deal -- even without the grab, we will still be able + to un-blank when there is user activity, since the server will + tell us. */ + /* #### No, that's not true: if we don't have a keyboard grab, + then we can't read passwords to unlock. + */ + ok = True; +# endif /* 0 */ + + if (!ok) + return False; + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->real_screen_p) + save_real_vroot (ssi); + store_vroot_property (si->dpy, + ssi->screensaver_window, + ssi->screensaver_window); + +#ifdef HAVE_XF86VMODE + { + int ev, er; + if (!XF86VidModeQueryExtension (si->dpy, &ev, &er) || + !safe_XF86VidModeGetViewPort (si->dpy, i, + &ssi->blank_vp_x, + &ssi->blank_vp_y)) + ssi->blank_vp_x = ssi->blank_vp_y = -1; + } +#endif /* HAVE_XF86VMODE */ + } + + raise_window (si, False, False, False); + + si->screen_blanked_p = True; + si->blank_time = time ((time_t) 0); + si->last_wall_clock_time = 0; + + store_saver_status (si); /* store blank time */ + + return True; +} + + +void +unblank_screen (saver_info *si) +{ + saver_preferences *p = &si->prefs; + Bool unfade_p = (si->fading_possible_p && p->unfade_p); + int i; + + monitor_power_on (si, True); + reset_watchdog_timer (si, False); + + if (si->demoing_p) + unfade_p = False; + + if (unfade_p) + { + Window *current_windows = (Window *) + calloc(sizeof(Window), si->nscreens); + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + current_windows[i] = ssi->screensaver_window; + /* Ensure that the default background of the window is really black, + not a pixmap or something. (This does not clear the window.) */ + XSetWindowBackground (si->dpy, ssi->screensaver_window, + ssi->black_pixel); + } + + if (p->verbose_p) fprintf (stderr, "%s: unfading...\n", blurb()); + + + XSync (si->dpy, False); + XGrabServer (si->dpy); /* ############ DANGER! */ + XSync (si->dpy, False); + + /* Clear the stderr layer on each screen. + */ + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + clear_stderr (ssi); + } + + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + + fade_screens (si->dpy, 0, + current_windows, si->nscreens, + p->fade_seconds/1000, p->fade_ticks, + False, False); + + free(current_windows); + current_windows = 0; + + if (p->verbose_p) fprintf (stderr, "%s: unfading done.\n", blurb()); + } + else + { + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + if (ssi->cmap) + { + Colormap c = DefaultColormapOfScreen (ssi->screen); + /* avoid technicolor */ + XClearWindow (si->dpy, ssi->screensaver_window); + if (c) XInstallColormap (si->dpy, c); + } + XUnmapWindow (si->dpy, ssi->screensaver_window); + } + } + + + /* If the focus window does has a non-default colormap, then install + that colormap as well. (On SGIs, this will cause both the root map + and the focus map to be installed simultaneously. It'd be nice to + pick up the other colormaps that had been installed, too; perhaps + XListInstalledColormaps could be used for that?) + */ + { + Window focus = 0; + int revert_to; + XGetInputFocus (si->dpy, &focus, &revert_to); + if (focus && focus != PointerRoot && focus != None) + { + XWindowAttributes xgwa; + xgwa.colormap = 0; + XGetWindowAttributes (si->dpy, focus, &xgwa); + if (xgwa.colormap && + xgwa.colormap != DefaultColormapOfScreen (xgwa.screen)) + XInstallColormap (si->dpy, xgwa.colormap); + } + } + + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + kill_xsetroot_data (si->dpy, ssi->screensaver_window, p->verbose_p); + } + + store_saver_status (si); /* store unblank time */ + ungrab_keyboard_and_mouse (si); + restore_real_vroot (si); + + /* Unmap the windows a second time, dammit -- just to avoid a race + with the screen-grabbing hacks. (I'm not sure if this is really + necessary; I'm stabbing in the dark now.) + */ + for (i = 0; i < si->nscreens; i++) + XUnmapWindow (si->dpy, si->screens[i].screensaver_window); + + si->screen_blanked_p = False; + si->blank_time = time ((time_t) 0); + si->last_wall_clock_time = 0; + + store_saver_status (si); /* store unblank time */ +} + + +/* Transfer any grabs from the old window to the new. + Actually I think none of this is necessary, since we always + hold our grabs on the root window, but I wrote this before + re-discovering that... + */ +static void +maybe_transfer_grabs (saver_screen_info *ssi, + Window old_w, Window new_w, + int new_screen_no) +{ + saver_info *si = ssi->global; + + /* If the old window held our mouse grab, transfer the grab to the new + window. (Grab the server while so doing, to avoid a race condition.) + */ + if (old_w == si->mouse_grab_window) + { + XGrabServer (si->dpy); /* ############ DANGER! */ + ungrab_mouse (si); + grab_mouse (si, ssi->screensaver_window, + (si->demoing_p ? 0 : ssi->cursor), + new_screen_no); + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + } + + /* If the old window held our keyboard grab, transfer the grab to the new + window. (Grab the server while so doing, to avoid a race condition.) + */ + if (old_w == si->keyboard_grab_window) + { + XGrabServer (si->dpy); /* ############ DANGER! */ + ungrab_kbd(si); + grab_kbd(si, ssi->screensaver_window, ssi->number); + XUngrabServer (si->dpy); + XSync (si->dpy, False); /* ###### (danger over) */ + } +} + + +static Visual * +get_screen_gl_visual (saver_info *si, int real_screen_number) +{ + int i; + int nscreens = ScreenCount (si->dpy); + + if (! si->best_gl_visuals) + si->best_gl_visuals = (Visual **) + calloc (nscreens + 1, sizeof (*si->best_gl_visuals)); + + for (i = 0; i < nscreens; i++) + if (! si->best_gl_visuals[i]) + si->best_gl_visuals[i] = + get_best_gl_visual (si, ScreenOfDisplay (si->dpy, i)); + + if (real_screen_number < 0 || real_screen_number >= nscreens) abort(); + return si->best_gl_visuals[real_screen_number]; +} + + +Bool +select_visual (saver_screen_info *ssi, const char *visual_name) +{ + XWindowAttributes xgwa; + saver_info *si = ssi->global; + saver_preferences *p = &si->prefs; + Bool install_cmap_p = p->install_cmap_p; + Bool was_installed_p = (ssi->cmap != DefaultColormapOfScreen(ssi->screen)); + Visual *new_v = 0; + Bool got_it; + + /* On some systems (most recently, MacOS X) OpenGL programs get confused + when you kill one and re-start another on the same window. So maybe + it's best to just always destroy and recreate the xscreensaver window + when changing hacks, instead of trying to reuse the old one? + */ + Bool always_recreate_window_p = True; + + get_screen_gl_visual (si, 0); /* let's probe all the GL visuals early */ + + /* We make sure the existing window is actually on ssi->screen before + trying to use it, in case things moved around radically when monitors + were added or deleted. If we don't do this we could get a BadMatch + even though the depths match. I think. + */ + memset (&xgwa, 0, sizeof(xgwa)); + if (ssi->screensaver_window) + XGetWindowAttributes (si->dpy, ssi->screensaver_window, &xgwa); + + if (visual_name && *visual_name) + { + if (!strcmp(visual_name, "default-i") || + !strcmp(visual_name, "Default-i") || + !strcmp(visual_name, "Default-I") + ) + { + visual_name = "default"; + install_cmap_p = True; + } + else if (!strcmp(visual_name, "default-n") || + !strcmp(visual_name, "Default-n") || + !strcmp(visual_name, "Default-N")) + { + visual_name = "default"; + install_cmap_p = False; + } + else if (!strcmp(visual_name, "gl") || + !strcmp(visual_name, "Gl") || + !strcmp(visual_name, "GL")) + { + new_v = get_screen_gl_visual (si, ssi->real_screen_number); + if (!new_v && p->verbose_p) + fprintf (stderr, "%s: no GL visuals.\n", progname); + } + + if (!new_v) + new_v = get_visual (ssi->screen, visual_name, True, False); + } + else + { + new_v = ssi->default_visual; + } + + got_it = !!new_v; + + if (new_v && new_v != DefaultVisualOfScreen(ssi->screen)) + /* It's not the default visual, so we have no choice but to install. */ + install_cmap_p = True; + + ssi->install_cmap_p = install_cmap_p; + + if ((ssi->screen != xgwa.screen) || + (new_v && + (always_recreate_window_p || + (ssi->current_visual != new_v) || + (install_cmap_p != was_installed_p)))) + { + Colormap old_c = ssi->cmap; + Window old_w = ssi->screensaver_window; + if (! new_v) + new_v = ssi->current_visual; + + if (p->verbose_p) + { + fprintf (stderr, "%s: %d: visual ", blurb(), ssi->number); + describe_visual (stderr, ssi->screen, new_v, install_cmap_p); +#if 0 + fprintf (stderr, "%s: from ", blurb()); + describe_visual (stderr, ssi->screen, ssi->current_visual, + was_installed_p); +#endif + } + + reset_stderr (ssi); + ssi->current_visual = new_v; + ssi->current_depth = visual_depth(ssi->screen, new_v); + ssi->cmap = 0; + ssi->screensaver_window = 0; + + initialize_screensaver_window_1 (ssi); + + /* stderr_overlay_window is a child of screensaver_window, so we need + to destroy that as well (actually, we just need to invalidate and + drop our pointers to it, but this will destroy it, which is ok so + long as it happens before old_w itself is destroyed.) */ + reset_stderr (ssi); + + raise_window (si, True, True, False); + store_vroot_property (si->dpy, + ssi->screensaver_window, ssi->screensaver_window); + + /* Transfer any grabs from the old window to the new. */ + maybe_transfer_grabs (ssi, old_w, ssi->screensaver_window, ssi->number); + + /* Now we can destroy the old window without horking our grabs. */ + XDestroyWindow (si->dpy, old_w); + + if (p->verbose_p) + fprintf (stderr, "%s: %d: destroyed old saver window 0x%lx.\n", + blurb(), ssi->number, (unsigned long) old_w); + + if (old_c && + old_c != DefaultColormapOfScreen (ssi->screen) && + old_c != ssi->demo_cmap) + XFreeColormap (si->dpy, old_c); + } + + return got_it; +} diff --git a/driver/xdpyinfo.c b/driver/xdpyinfo.c new file mode 100644 index 00000000..9f679665 --- /dev/null +++ b/driver/xdpyinfo.c @@ -0,0 +1,1098 @@ +/* + * $ TOG: xdpyinfo.c /main/35 1998/02/09 13:57:05 kaleb $ + * + * xdpyinfo - print information about X display connecton + * + * +Copyright 1988, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT X Consortium + * + * GLX and Overlay support added by Jamie Zawinski , 11-Nov-99 + * + * To compile: + * cc -DHAVE_GLX xdpyinfo.c -o xdpyinfo -lGL -lX11 -lXext [-lXtst] -lm + * + * Other defines to consider: + * -DMITSHM -DHAVE_XDBE -DHAVE_XIE -DHAVE_XTEST -DHAVE_SYNC + * -DHAVE_XRECORD + */ + +#include +#include +#include /* for CARD32 */ +#include +#ifdef HAVE_XIE +#include +#endif /* HAVE_XIE */ +#ifdef HAVE_XTEST +#include +#endif /* HAVE_XTEST */ +#ifdef HAVE_XSYNC +#include +#endif /* HAVE_XSYNC */ +#ifdef HAVE_XDBE +#include +#endif /* HAVE_XDBE */ +#ifdef HAVE_XRECORD +#include +#endif /* HAVE_XRECORD */ +#ifdef MITSHM +#include +#endif +#include +#include + +#ifdef HAVE_GLX +# include +# include +#endif /* HAVE_GLX */ + +#define HAVE_OVERLAY /* jwz: no compile-time deps, so do this all the time */ + +char *ProgramName; +Bool queryExtensions = False; + +static int StrCmp(a, b) + char **a, **b; +{ + return strcmp(*a, *b); +} + + +#ifdef HAVE_GLX /* Added by jwz, 11-Nov-99 */ + +static void +print_glx_versions (dpy) + Display *dpy; +{ + /* Note: with Mesa 3.0, this lies: it prints the info from the + client's GL library, rather than the info from the GLX server. + + Note also that we can't protect these calls by only doing + them when the GLX extension is present, because with Mesa, + the server doesn't have that extension (but the GL library + works anyway.) + */ + int scr = DefaultScreen (dpy); + const char *vend, *vers; + vend = glXQueryServerString (dpy, scr, GLX_VENDOR); + if (!vend) return; + vers = glXQueryServerString (dpy, scr, GLX_VERSION); + printf ("GLX vendor: %s (%s)\n", + vend, (vers ? vers : "unknown version")); +} + +static void +print_glx_visual_info (dpy, vip) + Display *dpy; + XVisualInfo *vip; +{ + int status, value = False; + + status = glXGetConfig (dpy, vip, GLX_USE_GL, &value); + if (status == GLX_NO_EXTENSION) + /* dpy does not support the GLX extension. */ + return; + + if (status == GLX_BAD_VISUAL || value == False) + { + printf (" GLX supported: no\n"); + return; + } + else + { + printf (" GLX supported: yes\n"); + } + + if (!glXGetConfig (dpy, vip, GLX_LEVEL, &value) && + value != 0) + printf (" GLX level: %d\n", value); + + if (!glXGetConfig (dpy, vip, GLX_RGBA, &value) && value) + { + int r=0, g=0, b=0, a=0; + glXGetConfig (dpy, vip, GLX_RED_SIZE, &r); + glXGetConfig (dpy, vip, GLX_GREEN_SIZE, &g); + glXGetConfig (dpy, vip, GLX_BLUE_SIZE, &b); + glXGetConfig (dpy, vip, GLX_ALPHA_SIZE, &a); + printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n", + r, g, b, a); + + r=0, g=0, b=0, a=0; + glXGetConfig (dpy, vip, GLX_ACCUM_RED_SIZE, &r); + glXGetConfig (dpy, vip, GLX_ACCUM_GREEN_SIZE, &g); + glXGetConfig (dpy, vip, GLX_ACCUM_BLUE_SIZE, &b); + glXGetConfig (dpy, vip, GLX_ACCUM_ALPHA_SIZE, &a); + printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n", + r, g, b, a); + } + else + { + value = 0; + glXGetConfig (dpy, vip, GLX_BUFFER_SIZE, &value); + printf (" GLX type: indexed (%d)\n", value); + } + +# if 0 /* redundant */ + if (!glXGetConfig (dpy, vip, GLX_X_VISUAL_TYPE_EXT, &value)) + printf (" GLX class: %s\n", + (value == GLX_TRUE_COLOR_EXT ? "TrueColor" : + value == GLX_DIRECT_COLOR_EXT ? "DirectColor" : + value == GLX_PSEUDO_COLOR_EXT ? "PseudoColor" : + value == GLX_STATIC_COLOR_EXT ? "StaticColor" : + value == GLX_GRAY_SCALE_EXT ? "Grayscale" : + value == GLX_STATIC_GRAY_EXT ? "StaticGray" : "???")); +# endif + +# ifdef GLX_VISUAL_CAVEAT_EXT + if (!glXGetConfig (dpy, vip, GLX_VISUAL_CAVEAT_EXT, &value) && + value != GLX_NONE_EXT) + printf (" GLX rating: %s\n", + (value == GLX_NONE_EXT ? "none" : + value == GLX_SLOW_VISUAL_EXT ? "slow" : +# ifdef GLX_NON_CONFORMANT_EXT + value == GLX_NON_CONFORMANT_EXT ? "non-conformant" : +# endif + "???")); +# endif + + if (!glXGetConfig (dpy, vip, GLX_DOUBLEBUFFER, &value)) + printf (" GLX double-buffer: %s\n", (value ? "yes" : "no")); + + if (!glXGetConfig (dpy, vip, GLX_STEREO, &value) && + value) + printf (" GLX stereo: %s\n", (value ? "yes" : "no")); + + if (!glXGetConfig (dpy, vip, GLX_AUX_BUFFERS, &value) && + value != 0) + printf (" GLX aux buffers: %d\n", value); + + if (!glXGetConfig (dpy, vip, GLX_DEPTH_SIZE, &value)) + printf (" GLX depth size: %d\n", value); + + if (!glXGetConfig (dpy, vip, GLX_STENCIL_SIZE, &value) && + value != 0) + printf (" GLX stencil size: %d\n", value); + +# if defined(GL_SAMPLE_BUFFERS) +# define SB GL_SAMPLE_BUFFERS +# define SM GL_SAMPLES +# elif defined(GLX_SAMPLE_BUFFERS) +# define SB GLX_SAMPLE_BUFFERS +# define SM GLX_SAMPLES +# elif defined(GLX_SAMPLE_BUFFERS_ARB) +# define SB GLX_SAMPLE_BUFFERS_ARB +# define SM GLX_SAMPLES_ARB +# elif defined(GLX_SAMPLE_BUFFERS_SGIS) +# define SB GLX_SAMPLE_BUFFERS_SGIS +# define SM GLX_SAMPLES_SGIS +# endif + +# ifdef SB + if (!glXGetConfig (dpy, vip, SB, &value) && value != 0) + { + int bufs = value; + if (!glXGetConfig (dpy, vip, SM, &value)) + printf (" GLX multisample: %d, %d\n", bufs, value); + } +# endif /* SB */ + + if (!glXGetConfig (dpy, vip, GLX_TRANSPARENT_TYPE_EXT, &value) && + value != GLX_NONE_EXT) + { + if (value == GLX_NONE_EXT) + printf (" GLX transparency: none\n"); + else if (value == GLX_TRANSPARENT_INDEX_EXT) + { + if (!glXGetConfig (dpy, vip, GLX_TRANSPARENT_INDEX_VALUE_EXT,&value)) + printf (" GLX transparency: indexed (%d)\n", value); + } + else if (value == GLX_TRANSPARENT_RGB_EXT) + { + int r=0, g=0, b=0, a=0; + glXGetConfig (dpy, vip, GLX_TRANSPARENT_RED_VALUE_EXT, &r); + glXGetConfig (dpy, vip, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g); + glXGetConfig (dpy, vip, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b); + glXGetConfig (dpy, vip, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a); + printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n", + r, g, b, a); + } + } +} +#endif /* HAVE_GLX */ + + +#ifdef HAVE_OVERLAY /* Added by jwz, 11-Nov-99 */ + + /* If the server's root window contains a SERVER_OVERLAY_VISUALS property, + then that identifies the visuals which correspond to the video hardware's + overlay planes. Windows created in these kinds of visuals may have + transparent pixels that let other layers shine through. + + This might not be an X Consortium standard, but it turns out that + SGI, HP, DEC, and IBM all use this same mechanism. So that's close + enough for me. + + Documentation on the SERVER_OVERLAY_VISUALS property can be found at: + http://www.hp.com/xwindow/sharedInfo/Whitepapers/Visuals/server_overlay_visuals.html + */ + +struct overlay +{ + CARD32 visual_id; + CARD32 transparency; /* 0: none; 1: pixel; 2: mask */ + CARD32 value; /* the transparent pixel */ + CARD32 layer; /* -1: underlay; 0: normal; 1: popup; 2: overlay */ +}; + +struct overlay_list +{ + int count; + struct overlay *list; +}; + +static struct overlay_list *overlays = 0; + +static void +find_overlay_info (dpy) + Display *dpy; +{ + int screen; + Atom OVERLAY = XInternAtom (dpy, "SERVER_OVERLAY_VISUALS", False); + + overlays = (struct overlay_list *) calloc (sizeof (struct overlay_list), + ScreenCount (dpy)); + + for (screen = 0; screen < ScreenCount (dpy); screen++) + { + Window window = RootWindow (dpy, screen); + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + struct overlay *data = 0; + int result = XGetWindowProperty (dpy, window, OVERLAY, + 0, (65536 / sizeof (long)), False, + OVERLAY, &actual_type, &actual_format, + &nitems, &bytes_after, + (unsigned char **) &data); + if (result == Success && + actual_type == OVERLAY && + actual_format == 32 && + nitems > 0) + { + overlays[screen].count = (nitems / + (sizeof(struct overlay) / sizeof(CARD32))); + overlays[screen].list = data; + } + else if (data) + XFree((char *) data); + } +} + +static void +print_overlay_visual_info (vip) + XVisualInfo *vip; +{ + int i; + int vis = vip->visualid; + int scr = vip->screen; + if (!overlays) return; + for (i = 0; i < overlays[scr].count; i++) + if (vis == overlays[scr].list[i].visual_id) + { + struct overlay *ov = &overlays[scr].list[i]; + printf (" Overlay info: layer %ld (%s), ", + (long) ov->layer, + (ov->layer == -1 ? "underlay" : + ov->layer == 0 ? "normal" : + ov->layer == 1 ? "popup" : + ov->layer == 2 ? "overlay" : "???")); + if (ov->transparency == 1) + printf ("transparent pixel %lu\n", (unsigned long) ov->value); + else if (ov->transparency == 2) + printf ("transparent mask 0x%x\n", (unsigned long) ov->value); + else + printf ("opaque\n"); + } +} +#endif /* HAVE_OVERLAY */ + + +void +print_extension_info (dpy) + Display *dpy; +{ + int n = 0; + char **extlist = XListExtensions (dpy, &n); + + printf ("number of extensions: %d\n", n); + + if (extlist) { + register int i; + int opcode, event, error; + + qsort(extlist, n, sizeof(char *), StrCmp); + for (i = 0; i < n; i++) { + if (!queryExtensions) { + printf (" %s\n", extlist[i]); + continue; + } + XQueryExtension(dpy, extlist[i], &opcode, &event, &error); + printf (" %s (opcode: %d", extlist[i], opcode); + if (event) + printf (", base event: %d", event); + if (error) + printf (", base error: %d", error); + printf(")\n"); + } + /* do not free, Xlib can depend on contents being unaltered */ + /* XFreeExtensionList (extlist); */ + } +} + +void +print_display_info (dpy) + Display *dpy; +{ + char dummybuf[40]; + char *cp; + int minkeycode, maxkeycode; + int i, n; + long req_size; + XPixmapFormatValues *pmf; + Window focuswin; + int focusrevert; + + printf ("name of display: %s\n", DisplayString (dpy)); + printf ("version number: %d.%d\n", + ProtocolVersion (dpy), ProtocolRevision (dpy)); + printf ("vendor string: %s\n", ServerVendor (dpy)); + printf ("vendor release number: %d\n", VendorRelease (dpy)); + +#ifdef HAVE_GLX + print_glx_versions (dpy); +#endif /* HAVE_GLX */ + + req_size = XExtendedMaxRequestSize (dpy); + if (!req_size) req_size = XMaxRequestSize (dpy); + printf ("maximum request size: %ld bytes\n", req_size * 4); + printf ("motion buffer size: %d\n", XDisplayMotionBufferSize (dpy)); + + switch (BitmapBitOrder (dpy)) { + case LSBFirst: cp = "LSBFirst"; break; + case MSBFirst: cp = "MSBFirst"; break; + default: + sprintf (dummybuf, "unknown order %d", BitmapBitOrder (dpy)); + cp = dummybuf; + break; + } + printf ("bitmap unit, bit order, padding: %d, %s, %d\n", + BitmapUnit (dpy), cp, BitmapPad (dpy)); + + switch (ImageByteOrder (dpy)) { + case LSBFirst: cp = "LSBFirst"; break; + case MSBFirst: cp = "MSBFirst"; break; + default: + sprintf (dummybuf, "unknown order %d", ImageByteOrder (dpy)); + cp = dummybuf; + break; + } + printf ("image byte order: %s\n", cp); + + pmf = XListPixmapFormats (dpy, &n); + printf ("number of supported pixmap formats: %d\n", n); + if (pmf) { + printf ("supported pixmap formats:\n"); + for (i = 0; i < n; i++) { + printf (" depth %d, bits_per_pixel %d, scanline_pad %d\n", + pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad); + } + XFree ((char *) pmf); + } + + + /* + * when we get interfaces to the PixmapFormat stuff, insert code here + */ + + XDisplayKeycodes (dpy, &minkeycode, &maxkeycode); + printf ("keycode range: minimum %d, maximum %d\n", + minkeycode, maxkeycode); + + XGetInputFocus (dpy, &focuswin, &focusrevert); + printf ("focus: "); + switch (focuswin) { + case PointerRoot: + printf ("PointerRoot\n"); + break; + case None: + printf ("None\n"); + break; + default: + printf("window 0x%lx, revert to ", focuswin); + switch (focusrevert) { + case RevertToParent: + printf ("Parent\n"); + break; + case RevertToNone: + printf ("None\n"); + break; + case RevertToPointerRoot: + printf ("PointerRoot\n"); + break; + default: /* should not happen */ + printf ("%d\n", focusrevert); + break; + } + break; + } + + print_extension_info (dpy); + + printf ("default screen number: %d\n", DefaultScreen (dpy)); + printf ("number of screens: %d\n", ScreenCount (dpy)); +} + +void +print_visual_info (vip) + XVisualInfo *vip; +{ + char errorbuf[40]; /* for sprintfing into */ + char *class = NULL; /* for printing */ + + switch (vip->class) { + case StaticGray: class = "StaticGray"; break; + case GrayScale: class = "GrayScale"; break; + case StaticColor: class = "StaticColor"; break; + case PseudoColor: class = "PseudoColor"; break; + case TrueColor: class = "TrueColor"; break; + case DirectColor: class = "DirectColor"; break; + default: + sprintf (errorbuf, "unknown class %d", vip->class); + class = errorbuf; + break; + } + + printf (" visual:\n"); + printf (" visual id: 0x%lx\n", vip->visualid); + printf (" class: %s\n", class); + printf (" depth: %d plane%s\n", vip->depth, + vip->depth == 1 ? "" : "s"); + if (vip->class == TrueColor || vip->class == DirectColor) + printf (" available colormap entries: %d per subfield\n", + vip->colormap_size); + else + printf (" available colormap entries: %d\n", + vip->colormap_size); + printf (" red, green, blue masks: 0x%lx, 0x%lx, 0x%lx\n", + vip->red_mask, vip->green_mask, vip->blue_mask); + printf (" significant bits in color specification: %d bits\n", + vip->bits_per_rgb); +} + +void +print_screen_info (dpy, scr) + Display *dpy; + int scr; +{ + Screen *s = ScreenOfDisplay (dpy, scr); /* opaque structure */ + XVisualInfo viproto; /* fill in for getting info */ + XVisualInfo *vip; /* retured info */ + int nvi; /* number of elements returned */ + int i; /* temp variable: iterator */ + char eventbuf[80]; /* want 79 chars per line + nul */ + static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED"; + double xres, yres; + int ndepths = 0, *depths = NULL; + unsigned int width, height; + + + /* + * there are 2.54 centimeters to an inch; so there are 25.4 millimeters. + * + * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) + * = N pixels / (M inch / 25.4) + * = N * 25.4 pixels / M inch + */ + + xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) / + ((double) DisplayWidthMM(dpy,scr))); + yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) / + ((double) DisplayHeightMM(dpy,scr))); + + printf ("\n"); + printf ("screen #%d:\n", scr); + printf (" dimensions: %dx%d pixels (%dx%d millimeters)\n", + DisplayWidth (dpy, scr), DisplayHeight (dpy, scr), + DisplayWidthMM(dpy, scr), DisplayHeightMM (dpy, scr)); + printf (" resolution: %dx%d dots per inch\n", + (int) (xres + 0.5), (int) (yres + 0.5)); + depths = XListDepths (dpy, scr, &ndepths); + if (!depths) ndepths = 0; + printf (" depths (%d): ", ndepths); + for (i = 0; i < ndepths; i++) { + printf ("%d", depths[i]); + if (i < ndepths - 1) { + putchar (','); + putchar (' '); + } + } + putchar ('\n'); + if (depths) XFree ((char *) depths); + printf (" root window id: 0x%lx\n", RootWindow (dpy, scr)); + printf (" depth of root window: %d plane%s\n", + DisplayPlanes (dpy, scr), + DisplayPlanes (dpy, scr) == 1 ? "" : "s"); + printf (" number of colormaps: minimum %d, maximum %d\n", + MinCmapsOfScreen(s), MaxCmapsOfScreen(s)); + printf (" default colormap: 0x%lx\n", DefaultColormap (dpy, scr)); + printf (" default number of colormap cells: %d\n", + DisplayCells (dpy, scr)); + printf (" preallocated pixels: black %d, white %d\n", + BlackPixel (dpy, scr), WhitePixel (dpy, scr)); + printf (" options: backing-store %s, save-unders %s\n", + (DoesBackingStore (s) == NotUseful) ? no : + ((DoesBackingStore (s) == Always) ? yes : when), + DoesSaveUnders (s) ? yes : no); + XQueryBestSize (dpy, CursorShape, RootWindow (dpy, scr), 65535, 65535, + &width, &height); + if (width == 65535 && height == 65535) + printf (" largest cursor: unlimited\n"); + else + printf (" largest cursor: %dx%d\n", width, height); + printf (" current input event mask: 0x%lx\n", EventMaskOfScreen (s)); + (void) print_event_mask (eventbuf, 79, 4, EventMaskOfScreen (s)); + + + nvi = 0; + viproto.screen = scr; + vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi); + printf (" number of visuals: %d\n", nvi); + printf (" default visual id: 0x%lx\n", + XVisualIDFromVisual (DefaultVisual (dpy, scr))); + for (i = 0; i < nvi; i++) { + print_visual_info (vip+i); +#ifdef HAVE_OVERLAY + print_overlay_visual_info (vip+i); +#endif /* HAVE_OVERLAY */ +#ifdef HAVE_GLX + print_glx_visual_info (dpy, vip+i); +#endif /* HAVE_GLX */ + } + if (vip) XFree ((char *) vip); +} + +/* + * The following routine prints out an event mask, wrapping events at nice + * boundaries. + */ + +#define MASK_NAME_WIDTH 25 + +static struct _event_table { + char *name; + long value; +} event_table[] = { + { "KeyPressMask ", KeyPressMask }, + { "KeyReleaseMask ", KeyReleaseMask }, + { "ButtonPressMask ", ButtonPressMask }, + { "ButtonReleaseMask ", ButtonReleaseMask }, + { "EnterWindowMask ", EnterWindowMask }, + { "LeaveWindowMask ", LeaveWindowMask }, + { "PointerMotionMask ", PointerMotionMask }, + { "PointerMotionHintMask ", PointerMotionHintMask }, + { "Button1MotionMask ", Button1MotionMask }, + { "Button2MotionMask ", Button2MotionMask }, + { "Button3MotionMask ", Button3MotionMask }, + { "Button4MotionMask ", Button4MotionMask }, + { "Button5MotionMask ", Button5MotionMask }, + { "ButtonMotionMask ", ButtonMotionMask }, + { "KeymapStateMask ", KeymapStateMask }, + { "ExposureMask ", ExposureMask }, + { "VisibilityChangeMask ", VisibilityChangeMask }, + { "StructureNotifyMask ", StructureNotifyMask }, + { "ResizeRedirectMask ", ResizeRedirectMask }, + { "SubstructureNotifyMask ", SubstructureNotifyMask }, + { "SubstructureRedirectMask ", SubstructureRedirectMask }, + { "FocusChangeMask ", FocusChangeMask }, + { "PropertyChangeMask ", PropertyChangeMask }, + { "ColormapChangeMask ", ColormapChangeMask }, + { "OwnerGrabButtonMask ", OwnerGrabButtonMask }, + { NULL, 0 }}; + +int print_event_mask (buf, lastcol, indent, mask) + char *buf; /* string to write into */ + int lastcol; /* strlen(buf)+1 */ + int indent; /* amount by which to indent */ + long mask; /* event mask */ +{ + struct _event_table *etp; + int len; + int bitsfound = 0; + + buf[0] = buf[lastcol] = '\0'; /* just in case */ + +#define INDENT() { register int i; len = indent; \ + for (i = 0; i < indent; i++) buf[i] = ' '; } + + INDENT (); + + for (etp = event_table; etp->name; etp++) { + if (mask & etp->value) { + if (len + MASK_NAME_WIDTH > lastcol) { + puts (buf); + INDENT (); + } + strcpy (buf+len, etp->name); + len += MASK_NAME_WIDTH; + bitsfound++; + } + } + + if (bitsfound) puts (buf); + +#undef INDENT + + return (bitsfound); +} + +void +print_standard_extension_info(dpy, extname, majorrev, minorrev) + Display *dpy; + char *extname; + int majorrev, minorrev; +{ + int opcode, event, error; + + printf("%s version %d.%d ", extname, majorrev, minorrev); + + XQueryExtension(dpy, extname, &opcode, &event, &error); + printf ("opcode: %d", opcode); + if (event) + printf (", base event: %d", event); + if (error) + printf (", base error: %d", error); + printf("\n"); +} + +int +print_multibuf_info(dpy, extname) + Display *dpy; + char *extname; +{ + int i, j; /* temp variable: iterator */ + int nmono, nstereo; /* count */ + XmbufBufferInfo *mono_info = NULL, *stereo_info = NULL; /* arrays */ + static char *fmt = + " visual id, max buffers, depth: 0x%lx, %d, %d\n"; + int scr = 0; + int majorrev, minorrev; + + if (!XmbufGetVersion(dpy, &majorrev, &minorrev)) + return 0; + + print_standard_extension_info(dpy, extname, majorrev, minorrev); + + for (i = 0; i < ScreenCount (dpy); i++) + { + if (!XmbufGetScreenInfo (dpy, RootWindow(dpy, scr), &nmono, &mono_info, + &nstereo, &stereo_info)) { + fprintf (stderr, + "%s: unable to get multibuffer info for screen %d\n", + ProgramName, scr); + } else { + printf (" screen %d number of mono multibuffer types: %d\n", i, nmono); + for (j = 0; j < nmono; j++) { + printf (fmt, mono_info[j].visualid, mono_info[j].max_buffers, + mono_info[j].depth); + } + printf (" number of stereo multibuffer types: %d\n", nstereo); + for (j = 0; j < nstereo; j++) { + printf (fmt, stereo_info[j].visualid, + stereo_info[j].max_buffers, stereo_info[j].depth); + } + if (mono_info) XFree ((char *) mono_info); + if (stereo_info) XFree ((char *) stereo_info); + } + } + return 1; +} /* end print_multibuf_info */ + + +/* XIE stuff */ + +#ifdef HAVE_XIE + +char *subset_names[] = { NULL, "FULL", "DIS" }; +char *align_names[] = { NULL, "Alignable", "Arbitrary" }; +char *group_names[] = { /* 0 */ "Default", + /* 2 */ "ColorAlloc", + /* 4 */ "Constrain", + /* 6 */ "ConvertFromRGB", + /* 8 */ "ConvertToRGB", + /* 10 */ "Convolve", + /* 12 */ "Decode", + /* 14 */ "Dither", + /* 16 */ "Encode", + /* 18 */ "Gamut", + /* 20 */ "Geometry", + /* 22 */ "Histogram", + /* 24 */ "WhiteAdjust" + }; + +int +print_xie_info(dpy, extname) + Display *dpy; + char *extname; +{ + XieExtensionInfo *xieInfo; + int i; + int ntechs; + XieTechnique *techs; + XieTechniqueGroup prevGroup; + + if (!XieInitialize(dpy, &xieInfo )) + return 0; + + print_standard_extension_info(dpy, extname, + xieInfo->server_major_rev, xieInfo->server_minor_rev); + + printf(" service class: %s\n", subset_names[xieInfo->service_class]); + printf(" alignment: %s\n", align_names[xieInfo->alignment]); + printf(" uncnst_mantissa: %d\n", xieInfo->uncnst_mantissa); + printf(" uncnst_min_exp: %d\n", xieInfo->uncnst_min_exp); + printf(" uncnst_max_exp: %d\n", xieInfo->uncnst_max_exp); + printf(" cnst_levels:"); + for (i = 0; i < xieInfo->n_cnst_levels; i++) + printf(" %d", xieInfo->cnst_levels[i]); + printf("\n"); + + if (!XieQueryTechniques(dpy, xieValAll, &ntechs, &techs)) + return 1; + + prevGroup = -1; + + for (i = 0; i < ntechs; i++) + { + if (techs[i].group != prevGroup) + { + printf(" technique group: %s\n", group_names[techs[i].group >> 1]); + prevGroup = techs[i].group; + } + printf(" %s\tspeed: %d needs_param: %s number: %d\n", + techs[i].name, + techs[i].speed, (techs[i].needs_param ? "True " : "False"), + techs[i].number); + } + return 1; +} /* end print_xie_info */ + +#endif /* HAVE_XIE */ + + +#ifdef HAVE_XTEST +int +print_xtest_info(dpy, extname) + Display *dpy; + char *extname; +{ + int majorrev, minorrev, foo; + + if (!XTestQueryExtension(dpy, &foo, &foo, &majorrev, &minorrev)) + return 0; + print_standard_extension_info(dpy, extname, majorrev, minorrev); + return 1; +} +#endif /* HAVE_XTEST */ + +#ifdef HAVE_XSYNC +int +print_sync_info(dpy, extname) + Display *dpy; + char *extname; +{ + int majorrev, minorrev; + XSyncSystemCounter *syscounters; + int ncounters, i; + + if (!XSyncInitialize(dpy, &majorrev, &minorrev)) + return 0; + print_standard_extension_info(dpy, extname, majorrev, minorrev); + + syscounters = XSyncListSystemCounters(dpy, &ncounters); + printf(" system counters: %d\n", ncounters); + for (i = 0; i < ncounters; i++) + { + printf(" %s id: 0x%08x resolution_lo: %d resolution_hi: %d\n", + syscounters[i].name, syscounters[i].counter, + XSyncValueLow32(syscounters[i].resolution), + XSyncValueHigh32(syscounters[i].resolution)); + } + XSyncFreeSystemCounterList(syscounters); + return 1; +} +#endif /* HAVE_XSYNC */ + +int +print_shape_info(dpy, extname) + Display *dpy; + char *extname; +{ + int majorrev, minorrev; + + if (!XShapeQueryVersion(dpy, &majorrev, &minorrev)) + return 0; + print_standard_extension_info(dpy, extname, majorrev, minorrev); + return 1; +} + +#ifdef MITSHM +int +print_mitshm_info(dpy, extname) + Display *dpy; + char *extname; +{ + int majorrev, minorrev; + Bool sharedPixmaps; + + if (!XShmQueryVersion(dpy, &majorrev, &minorrev, &sharedPixmaps)) + return 0; + print_standard_extension_info(dpy, extname, majorrev, minorrev); + printf(" shared pixmaps: "); + if (sharedPixmaps) + { + int format = XShmPixmapFormat(dpy); + printf("yes, format: %d\n", format); + } + else + { + printf("no\n"); + } + return 1; +} +#endif /* MITSHM */ + +#ifdef HAVE_XDBE +int +print_dbe_info(dpy, extname) + Display *dpy; + char *extname; +{ + int majorrev, minorrev; + XdbeScreenVisualInfo *svi; + int numscreens = 0; + int iscrn, ivis; + + if (!XdbeQueryExtension(dpy, &majorrev, &minorrev)) + return 0; + + print_standard_extension_info(dpy, extname, majorrev, minorrev); + svi = XdbeGetVisualInfo(dpy, (Drawable *)NULL, &numscreens); + for (iscrn = 0; iscrn < numscreens; iscrn++) + { + printf(" Double-buffered visuals on screen %d\n", iscrn); + for (ivis = 0; ivis < svi[iscrn].count; ivis++) + { + printf(" visual id 0x%lx depth %d perflevel %d\n", + svi[iscrn].visinfo[ivis].visual, + svi[iscrn].visinfo[ivis].depth, + svi[iscrn].visinfo[ivis].perflevel); + } + } + XdbeFreeVisualInfo(svi); + return 1; +} +#endif /* HAVE_XDBE */ + +#ifdef HAVE_XRECORD +int +print_record_info(dpy, extname) + Display *dpy; + char *extname; +{ + int majorrev, minorrev; + + if (!XRecordQueryVersion(dpy, &majorrev, &minorrev)) + return 0; + print_standard_extension_info(dpy, extname, majorrev, minorrev); + return 1; +} +#endif /* HAVE_XRECORD */ + +/* utilities to manage the list of recognized extensions */ + + +typedef int (*ExtensionPrintFunc)( +#if NeedFunctionPrototypes + Display *, char * +#endif +); + +typedef struct { + char *extname; + ExtensionPrintFunc printfunc; + Bool printit; +} ExtensionPrintInfo; + +ExtensionPrintInfo known_extensions[] = +{ +#ifdef MITSHM + {"MIT-SHM", print_mitshm_info, False}, +#endif /* MITSHM */ + {MULTIBUFFER_PROTOCOL_NAME, print_multibuf_info, False}, + {"SHAPE", print_shape_info, False}, +#ifdef HAVE_XSYNC + {SYNC_NAME, print_sync_info, False}, +#endif /* HAVE_XSYNC */ +#ifdef HAVE_XIE + {xieExtName, print_xie_info, False}, +#endif /* HAVE_XIE */ +#ifdef HAVE_XTEST + {XTestExtensionName, print_xtest_info, False}, +#endif /* HAVE_XTEST */ +#ifdef HAVE_XDBE + {"DOUBLE-BUFFER", print_dbe_info, False}, +#endif /* HAVE_XDBE */ +#ifdef HAVE_XRECORD + {"RECORD", print_record_info, False} +#endif /* HAVE_XRECORD */ + /* add new extensions here */ + /* wish list: PEX XKB LBX */ +}; + +int num_known_extensions = sizeof known_extensions / sizeof known_extensions[0]; + +void +print_known_extensions(f) + FILE *f; +{ + int i; + for (i = 0; i < num_known_extensions; i++) + { + fprintf(f, "%s ", known_extensions[i].extname); + } +} + +void +mark_extension_for_printing(extname) + char *extname; +{ + int i; + + if (strcmp(extname, "all") == 0) + { + for (i = 0; i < num_known_extensions; i++) + known_extensions[i].printit = True; + } + else + { + for (i = 0; i < num_known_extensions; i++) + { + if (strcmp(extname, known_extensions[i].extname) == 0) + { + known_extensions[i].printit = True; + return; + } + } + printf("%s extension not supported by %s\n", extname, ProgramName); + } +} + +void +print_marked_extensions(dpy) + Display *dpy; +{ + int i; + for (i = 0; i < num_known_extensions; i++) + { + if (known_extensions[i].printit) + { + printf("\n"); + if (! (*known_extensions[i].printfunc)(dpy, + known_extensions[i].extname)) + { + printf("%s extension not supported by server\n", + known_extensions[i].extname); + } + } + } +} + +static void usage () +{ + fprintf (stderr, "usage: %s [options]\n", ProgramName); + fprintf (stderr, "-display displayname\tserver to query\n"); + fprintf (stderr, "-queryExtensions\tprint info returned by XQueryExtension\n"); + fprintf (stderr, "-ext all\t\tprint detailed info for all supported extensions\n"); + fprintf (stderr, "-ext extension-name\tprint detailed info for extension-name if one of:\n "); + print_known_extensions(stderr); + fprintf (stderr, "\n"); + exit (1); +} + +int main (argc, argv) + int argc; + char *argv[]; +{ + Display *dpy; /* X connection */ + char *displayname = NULL; /* server to contact */ + int i; /* temp variable: iterator */ + Bool multibuf = False; + int mbuf_event_base, mbuf_error_base; + + ProgramName = argv[0]; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + int len = strlen(arg); + + if (!strncmp("-display", arg, len)) { + if (++i >= argc) usage (); + displayname = argv[i]; + } else if (!strncmp("-queryExtensions", arg, len)) { + queryExtensions = True; + } else if (!strncmp("-ext", arg, len)) { + if (++i >= argc) usage (); + mark_extension_for_printing(argv[i]); + } else + usage (); + } + + dpy = XOpenDisplay (displayname); + if (!dpy) { + fprintf (stderr, "%s: unable to open display \"%s\".\n", + ProgramName, XDisplayName (displayname)); + exit (1); + } + +#ifdef HAVE_OVERLAY + find_overlay_info (dpy); +#endif /* HAVE_OVERLAY */ + + print_display_info (dpy); + for (i = 0; i < ScreenCount (dpy); i++) { + print_screen_info (dpy, i); + } + + print_marked_extensions(dpy); + + XCloseDisplay (dpy); + exit (0); +} diff --git a/driver/xscreensaver-command.c b/driver/xscreensaver-command.c new file mode 100644 index 00000000..0057438a --- /dev/null +++ b/driver/xscreensaver-command.c @@ -0,0 +1,450 @@ +/* xscreensaver-command, Copyright (c) 1991-2013 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +/* #include / * for CARD32 */ +#include +#include +#include /* for XGetClassHint() */ +#include + +#include /* only needed to get through xscreensaver.h */ + + +/* You might think that to read an array of 32-bit quantities out of a + server-side property, you would pass an array of 32-bit data quantities + into XGetWindowProperty(). You would be wrong. You have to use an array + of longs, even if long is 64 bits (using 32 of each 64.) + */ +typedef long PROP32; + +#include "remote.h" +#include "version.h" + +#ifdef _VROOT_H_ +ERROR! you must not include vroot.h in this file +#endif + +char *progname; + +Atom XA_VROOT; +Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; +Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO, XA_EXIT; +Atom XA_BLANK, XA_LOCK; +static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV; +static Atom XA_RESTART, XA_PREFS, XA_THROTTLE, XA_UNTHROTTLE; + +static char *screensaver_version; +# ifdef __GNUC__ + __extension__ /* don't warn about "string length is greater than the + length ISO C89 compilers are required to support" in the + usage string... */ +# endif +static char *usage = "\n\ +usage: %s -

            "]; + t = [t stringByReplacingOccurrencesOfString:@"\n " + withString:@"
            "]; + + NSString *h = @""; + for (NSString *s in + [t componentsSeparatedByCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]]) { + if ([s hasPrefix:@"http://"] || + [s hasPrefix:@"https://"]) { + char *anchor = anchorize ([s cStringUsingEncoding:NSUTF8StringEncoding]); + NSString *a2 = [NSString stringWithCString: anchor + encoding: NSUTF8StringEncoding]; + s = [NSString stringWithFormat: @"
    %@
    ", s, a2]; + free (anchor); + } + h = [NSString stringWithFormat: @"%@ %@", h, s]; + } + [self setHTML: h]; +} + + +-(BOOL) webView:(UIWebView *)wv + shouldStartLoadWithRequest:(NSURLRequest *)req + navigationType:(UIWebViewNavigationType)type +{ + // Force clicked links to open in Safari, not in this window. + if (type == UIWebViewNavigationTypeLinkClicked) { + [[UIApplication sharedApplication] openURL:[req URL]]; + return NO; + } + return YES; +} + + +- (void) setFrame: (CGRect)r +{ + [super setFrame: r]; + r.origin.x = 0; + r.origin.y = 0; + [webView setFrame: r]; + [self setHTML: html]; + [webView reload]; +} + + +- (NSString *) stripTags:(NSString *)str +{ + NSString *result = @""; + + str = [str stringByReplacingOccurrencesOfString:@"

  • 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ar.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ar.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..858a71fae820a04fe9b7cebaeef3d0524600561a GIT binary patch literal 8896 zcmds->u*y>5XJY?N=5x2aFPZG6UR+}R!~*oByLQ26)39u(RpGKoXAN?`RCi7-;O7H zuOBfWj6`L{zW46q?#`S&b9OfW{?iDxPzle%vA%cp{Z60#&a6HlEi}TlFdr7fYWN{M)RV=qHn@5dI^i_6rhZRXd+PT>S4aBo zT=w446W-EIwfm||8E-sOy-GOO^ZhWVt3P#ruGZB4kghAb>xQ=~_u7o_R4qFyInvW^ znv=hS-j7svu3Ed{jmq=Ld+PBbJkV?^;aC05hgxh!%`yHK*Wz~E)OD_%=h=>1v8}S@ zSk={z%GT`g32`WqDA6&)@6%Nd5tjMekC7FJa`ZuDUAk2#wS^ zRzLIy!j3hjGnF!0yuYWiuKL_hXnm@3u8V#&j2W8fr>P!J)Ykf-FUAIr4|E0g!2YuC zN3mpB%X2(S7NH*X9fN0T$xIo4NB#FSwv0KDQwiI`%!WLR=QAb>=!-w5dUxV;;o?O? zRx8zSr}~DOm4sV*0g>xMUNz1oJT-Oqvz~9nyTa~jdPezOJzGd#buQ=2JLEkD~P9eP~TS1_fly__*QDgsJGN_ zRd%R^TWKZMb=OYsq1T2!kM#uW%?ka-XnY$x?FyOww2hPayJpe*W<&qLO+J#hogvd{3w5eyX}OZQTyH=L@8S}#mqG4Uvlv6v$eRzl`tMUi& z+wNNG&!Qo*9@S7+RGn=+Y|38Ktd9!pChLvrefNS#%%V3w-|BE38j0xWc3;pP+5u}7 z_51(Dvisrhgzk>84{i*7Y+8H2Z$_7g=;wP$N$ z))(T4XKAN1o@ZybkN8yH9Nt+v23<+9o7_<>BU|HZev;z3NNmhr*mmusddJifd_r&R ztciJ^U+L>Tu)e>$9PK8v!?f%LNM4ku*sUyF#>k?^!gE=H+)hf~qG{gu*lwq(GLMS3 zm!&Ox%!cqleB{2CYS})MC`+rY^nRaPS+%%jnZNJsO>>YBBkMs{z%yX$1r@NQUQv$a z{=QtcZ9{8`{1v&ZtUa*ieZ6_^tGu@oUKg~~xKX&(J%2GfYmj%^RTj|K37HzSVUb%- z#VLI9NVkQq)l1}{x7PJ>Mc-CwJ1P9E#87G8OHtqdA%9p7lDreEmo;@fSW)CKE$`G9 zzmfaA&=W_OMVd2>6*RG0$%aw~Mdaw(Oiyy=)Mr|pp^wb>U3q?!6_B_2y0dAGRWBbm zmvO2iduZHz+|r}#m~1vVxN+-wD->5WxmVT}S=-sJ?ML!|Rv$TQ_%f~boVm_8&bzLw zvc|@MzDq5y#o6PxJge#GCF&RPJ4p|Hn!jNP*55dPKQ8%uL;glZO!D_+Oc6aNVd`n= z9jz&tdLAB&0W8jwrS6p&fzphDmd09@>Run>{#W7|_Nm4$jO|pPoH-}5+j-An;w?(c zEChF1tQp(ilG;0xyH867_Z zVBB^JME--3+36E&irTiy`pG&cy0?=6YhfI1Cr_wWFU695^=npXsK*0+%8`Z>HIGO{ zootC$X$*dX<*I}6pyfD)V`P4MVcF%}mz_Y2#0MX)L~!O#PueQI2h`8%`sv2Xy0&fo}A%&Tel|R8bm%&}Ese zVs7rL?1tOG&JD{e<;y9~JWA*8a*j7g;BooSYGGbg;c=LU^2uT5RWfg2J!2Onk5_ii zlFk5N7!~HMlk$_G-eVtzGB=(j z|7h#D$UoQ+{ro80)URtiU&F(r&!;3l;;T=Za*o?q=e+WReiAb2Bx!mU`|4OyoZq+a z&$3Ud2~FnrdSdFjVjNt}|0QGwyxPj;wb>LdXiqdT*0+-|?pPlg>+`}%Q4{jMqACFO z#30TdEh1Y_oS2h!;r}?wm?e5y?%WVH98<1^@6t|$QsN5HlHP_-oO~Rn7^rRaUWb?A pNh$I@(b(7-fqPEjS)H!ke8194r`7pP#h9%rHohyC-Yo3A{sWd#6!QQ8 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/cs.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/cs.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..9bbb99686b37f7b1ce5dfbfbc6301cdec3712e69 GIT binary patch literal 8642 zcmd^^+ip`w6o$vQyh3hFRT>F3pthG)1tFjwq5w)MRk+)U9dP196x(s*3!a5n%Ow|i zfl596-&!7K_V#vKP&SpQ5Y9f#o>}W(|2oW?zy7=%ZijYw97g&*(C~^>tZiLUmt?*U&JlxllTjA@))vHj1v3 zp{_cbcc!bp{ub|MFZ6^}dN%r0V|mAl6OC(!sh)SkODQW^toNPb=M2WdLKt4 z-&kK3dehg_p6L|VVD`S=O*QHuywdw5`A{>?!aZrz4&Uj2y;fl1^QLt`>q0ZOHS?Qr zWYV03y;je#EcDj(Ki1n5ll!&aO~R$V;GW;T)@3MKJR9hKtS3{uUuzBZ46L7OOxI?g z*a~Cm#)>DB2Mh{n#FJd3b4kT2L%q$BLE>V8%$qRRd!9@+(pLsSBm|9bW#JpLb5o2t zkR-#fZqn?VW>e|ZG5MT-Gg-*V6z2F;cI@5Ju zU%~X8H;nISp0O~5F9Xf+(#DK5C-Y(1kz@iBq{aRnz3Z7}vCWR*$Gi!BXRq^=c{VkJ z+lo1u3)#@+&?Lj#PQ#bFUuLPZIO#YsL>R~T$nJ^0L{sEQjBoYSEhTnU(i#e&oZFuIq)Z z@6qnUxPhb>3km(poEgaj$3o->c`8VuQNpzBeMCE0SICd?!Ldey)v?*AY7KOVzSmvM zek3#;KQI6##{v#tYV;%!9ehmmU@YF0$9jC{*JJg8kT^BAk~!SVoSBaDOc)_0D8OwZ z7Muq+aOvrrLe}Z)ZO+u>Ln)g$yRhAnW*}OvwT>3Zf;8(8H-@rdTyL(?9}f-BA9cEI zh^aAOkrhFMNO9ko{%^8cHFL(i=4<9T>nEF=NakKZewhpDYHmo#ZfNX4s5zr=g>Ni> zC%%Jxo^giK#k0y>@qxH_Dcj~5r5rUpFEyD-U}O~`GDphfRY{3rcqcY!mLVfW_qfh- zT|u;pmS{?jO|607%=EYFhe^8V)61TDGsDr@wd`;1k!8=TM#so`=4&QGy`QGbm1bTc z^+T@rW8-&KKiJb=S??8k=M_b&6x|n^M1bf@ti>a#I!5yR6sNt;W(?X>FZA@6TA$jU zT02!xPtawG8=#jBwd8B7j zHpR++wh0w3*$~aDku2IKX4c$B*I|ot3@0*rwZdMD%85$*(?`7$ zmL>Z31^isD*1XmumN6UM493OXhj&e=IlW((=jP{28PzS5@~Zc#u$k9;Z!M3qYb96E zz4C5VedXsXqAk9TRP|LOSkMdcOjzF6c~^}$%)!2zOkVCekiByK@~j^5rFRs2Dqbhi z*P~XT9}~Np53wG3E!t3dsZb=uqk#s{+rS!t`Zee}GkFjz){F2pv^>VE8;pXI{ z?{}cM5q*YE8C7i_pT>$y{7W)FQ9fO3?X{+h+T3|u-nDqgpkAZP@I||<(=*w~yUg_N z@MveRdl^h1`cZcu%8K-nlP`OAqdNh&@L>AgjG=mqTzhCwQg1wJoNHRub6el|?z^mM zU8L>)2Rc2ft*NfkXjdA=s^~*>TJ7JQT+kJ*^YiaR?&*HljIaMF+ox&=_W9Yzu6cht zmq=XBzkp-xs`&1zuKma6ZZ0F;(B-{kmAUyB*K22D1s+&u=k1c6{VuojYW9#tSFvZO zG^^j`vtD1OcoMd=DEGkfWKSLCvc0cwJy=;ji_7hnXDi>=dnHI5B(tyTel#WR&(3*V?{dSh!NHI zGpkO6QWrX};&$GhNz|WS6Jy|7{h5$gW1M`{`35I1P4UW6SvN$yQl%Co9>z26oMF#} YT4ATIQDS`8PrD-1E`%>#xzsoQ8{|d4t^fc4 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/da.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/da.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..bcf691da5d74c63cc4a3b0185618f5535fdf8fa5 GIT binary patch literal 8818 zcmdU!TW=dh7>4JT{)$aS2~;!{aETBNw9qO&sUaXP9oub9Tqp7&AwL*?L$84Mnb*^q zS+8kQaMa35yx!gU<~zLKasK}6cDNau@Hiane_#J!=`#$IFxT&sFx8#YFbV_R8|cnq zIM;ukztG)@u7-MNNB3@q+u>Tc9&Us$!pGr`?%W7pF0WpOUYNzzyg$*^Ky=S^HP(0U z4fUSxu*)dEJ=MEBW5>DPYr;bJhha-szv%Zut9ko8UN`zR3P*aL-iE)KR`&E{th=Kq zQ`!USV?A5wt$ui^=b7_~D4vCHB~25)(ODQn2HupN-h_X$FHULYtsIv?AVtqldv7-JB&Omgp7gi z!VwlYTWY~N-d^;kLqf2B2fe;_(D>6IN` zi2|BIOXwKxxIT&6hFdf~(6f{){Q32Rgf=aH6#%;Q`r3T7zxi9nSE9 zY4}{fSFvMkWf|vDBfQ7^33GF;L{j+giT*^qbz$r%u0YnKC8CioX&kC>H3@%+9+Db+ zN8xqk%p6Ze!=4Hru?0H)Q!5YkgmvH+^bVqie$dnNXyc5qgkCg`ZtS~HwHkb~gQJDD z(nhN}n?}pSi!n`1c`aKYomZfPO<~w^i2sf$eQ9Ey$Of~La2(9E9GzM0-MCGnDNX#{YZ-lR6hS|}*ed#xOzHyo(v%O`r(GrZc zWyiNl|K^>{)qKOaKbGea@9tDQr0m>VK6Q@Xln3sL1N&7Q@5F<|U-HgXAKNN;zb8si zbFOH6XQpMpTZf_dLsBA8UE9=kz`M)6T6@%#(GGX;r_JdCOR*D~f+%>boSI{=YdqdT z4`juWzNs_ei#ji7JFqbkQlLW~N_iQde;OkxwI%U%HM^4WT%}N>W>4JH4%8;B$~pFx z_85ptsxG?sHM(5M)LGfw^BmsxM2#vM4LIVX2e=_llu^vG9Y#6H<>NQ zKQvvUz1%alby>!xtHfr_l|A}H(=3>9J?$9Z$_w z-3QW9;VpM1A2g}pi1h6ai~JAAr>gtWh4~t*BB=WS^e~B?tS2J$(#BNgtely!dtK=y z?IC08++C+I--0R~Lz-xPS74Fr&7kG`C`Dg;kBj}l&_uRK6~tBS-h_i9ch-Jb^5U6G zo=O<6o8yoS-H#c_)^^=gR}9#iPv&}GSsX-CB@Go{TuF8F&Rd@}wFE!KTm~AM3K^I5 zvi2LMlAbIv=U|$7raK8=Mj>54c)}-{Z}JZQknnXk-pRAjbFdzi345!`(r3Q*uOU8!w+PWTs=_jd!GGF)+!@= zMrXakDD9s8UNtIf&Mtzg`e{W`@iZH+wTrvwi)mT)nU8Ko{tk03S1bQqKvsbne20)lci#fkrvAASSiD zDbL0{0mf!bJ&Bv1@ur9a9_#5tZM)3>Uc@a{^gPAgc*ZzZHa2Q}K3Z~~Xf|`XCK57xFF(sg=4MHgs3djQ{JUlww`Wl#dCe?JV7*1`NY*p z(#?M4A)PJdih`3Oc26@1pEG!ZoN4*20DYBlZ>DpaCj6?^^!==aJES<%|MSTE+i5g$ zZ!&P!So_2wS8TjZj##v^VVaU=$!5z8d9nNm-?b(UcoA>v|abbH@*!=X&oS_&U9{ literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/de.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/de.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..664946d41478636bfb57080a57cca064a5b02c75 GIT binary patch literal 9246 zcmeI2T~i!I6o&iO{EA6R#H56jdTCh(0xA_rQo+R1y8#xmLUyU$g*E=({06U5>ihKB zLr?e45<(cPQfn)dnf^Q<@A>G{{PpMka4%HhaTw~kr{^pEdSMVI`aTIGwVZ{1*jL-W zT6V*0J?TGG>p*WkjagOOy>LI=3U|U%_&j_Z9;jt0d@*}_8R{^Ovl&0o+rHMF>g`zn z*XOI(YGIdt96i!l`q*)zaaA}~doSG9+fVvF)oez;j_;Me`r%0ZJ{tPQnpvyoSgrlY zlkdUm$Lc%PsJ-w~{fY8{R-A@!#7z~x*1vYHrkXp7v{#ys99U}--wtQ1BRBY^2U?-0 zr_o6F_c*@_FXD`89JwDy9;$aYw)P^`aJ(J{`uouTW(kGgU4MBgc^#`J@4cSMLC%8g>*aS$b#s5U|fj^`H>c9c= z=gklfeTHD>_agmB*1pVBpoJHaCzCdPL+t{_z%x6-V_(?EHV*aGmlO`v`>9%1!+MnJ zMx+C+Y-L(8Nmb!t*bpu^wAV(st5Imp{D9%tXm{IP)rd!;<7CF!BI|+&^lSZ3McXh^ zSc?Y3&XXt&xG{aTODf_%S9uXE&GmSGf84t&yM7bO9DXf`K=h>cdB);4eB@ffYF6(yV3Ez)n z{7#;W!lOkMvdin?-~HlNwl*1$``kP$>`pcow}}gu?F<#2Q>3sQoiWIT`~vU7Il;27 zW~K&a2EsV&kV82y#NDScYH&8dH_hiM?cNxFeBK_>OSTp3s zL}j=ry`O8yGQ~Wn{&0a#tz(mHfB~vo97W1*~))IM`$H^_)r`mmy z7sFOQsdAbBsF_w>r`CxtV71}QKB>-It&`dVRsE@29C3zMs)!&A+ou}N7$T=5ZX>p& zI|1ji>90%PF5<#=qC)wu6aLNfy4jllU7b@jmS=Y*Pp*r3>*pqi%5a+(_)ce{ge3dw z<~+V74h$z27rc7?Ec%8NbrLoC4693SibKnOBB#O(!a- zTHrS=_7b;=_W9_f#~h#6Cz&02|8#en@*XUVyD6{H*o~Im2Urv)^4P5u^^T^m8tbmK z3O~nn(I2);WIUFKua#Ti_20cl755%!WxKKECZfFCN*N!cvG&s<)^TUXP26J6#Jljhi}4X;Yd&Jhi|X0UWYQw;%NGhb=B9rOI?lh zTfU#Y)Dzw^jJ>DoOB-*Tt6vcodOisEboIOL7aC3Pck#N=-7vgSyZ1)EnMRgs8R_XT zuF2oQ>?5@;)Tt363R){M*WP^&4z5BmGqR`tCswI_SEW%-`;Iu4zv@6%|Jg|O7u z)4A@j*-{!eBw&@!mA$dWIO6JDea<5K-s-BC@k zKqubumF`#3W@t=noJWn&kN%F*xkj>5u zccm$d(M{{_hVJ{EK<05TK8k+5P3EX)C(j+*P z{Sec0tbym|K5a@hQPd?`A5~;=HsYKx(!lYr&FxkY1h%V#E7^ab_ zIFBF}{2C)U?Ads2oejWxj8(zHlMfzi#$A-}!&w8yIgHv|jZJP9&$PL9+P1=7%C#HX zAA~=nN0jmxux=jVx-aD`?8g!lZ_@{I?YAx0ZfGBUr(JPf`yUGV?Mk&9n!iw_HpX5> ze6DkLj?_r{H;(2xl5hT|-Ov!ZGOx)vI=wQ(KJ8SwlU=UIi*;;k8KeCujv#lgaxG(O z#3E*+NvkTQ z;wCjWaGh`pYMYss$3*vb@Cr}zNRujqcCv14&EMsFK8tBYML#{|M4l0L_Gg)txRLV- z^X4zq&lnjyBDk`}Rw|F?vw5sRQ*hNM;YEx)A%Zirn~Q>&-?t(x%~dyt#l(*=}{W%x~c1~eg6TLZ1 z!_?QizTRx4BV8Ha*4vTp2AXqI?{1`9=}NkmmeMEb{j{PtOX<_oyJxAF_H8xuN4o24 z-2hZ&t5`CE-*cY~qZ}^y`S2nxkjJIe6{zm%U)UUtG z{PaZS*uDf$pG!|yq^+*>jtoZWx=DM(C_50ReZ8IP360G}kJ|w{xo)zUm?q!=+p5x* z=*1c<<2Y<#S?{nKI`!)ed{6GxlIFXhW}CMi~|{NgwNZ-qzd}Gmle~2=kZ^g~(~D zm2e9EJ?%ddZEZG*y;k}%^zKO_NSXVdxSQ%34u{Dt3oqvlU&yNl=?AS~1Un0B_FeFh zy0pXI`R0lCW}h8f&)3|dJ(e(%HIUc2ewc$MD$^nFxIa15%=lCnaCB&Nl{U@S4>aF> zZclSE?XDfTW)z=5H+ZP~B$9P|bY7d@<2<=fhb)OAuS^47d5}j>n(i_VUmPpi zBDs|sErCJYcf-oNqGVMRpvRg1Ha#)Z7hXN@n^z0kU!o~OTnBZ7E!!a~54tHHy_?vYJYDGe5p&1K9r;(jY-FB1XpB$HPrsVO>;!8U1(dahV>X2R=y! zQqtkbcilXOdg8z3J!k+Nh?!#?Tj^e>ow7DX;< z(_FEZ($8^@ZbIY?uUY16-JFO1DOrO|3$@X63aLg_OYOg*Q7Vp*^dek2vs^^n@E*%N zs&q_B!``x_TS4vTaLhs$Oy(TQ^Xl^jy3gP0;4MHWG$O%&*8kH~ne z(YDGncA-~!qBvhxt!_fOA`;lX#+j+Z&x4N>k zuVgcHDY2f6@5;AG=rX=u39si~-eOwL!-d_^Nmp@GUBB=vN3bB@O!K~?6hE2v+ZuPI z6g{!_Sdu$PA5?W7zLS2u^X!$cW25n@=V9sIO`IrFf_AAB!_GVp(l^7d@M@=GCK|Jy z-LX}vldNHQNUy0_tyPHOl0 zD!6IE3Z?5WY|R(^su(8KXp^fK2B>zbn~Zf zzJyKIPv}aGmAPtNb~!lf(oj90*R!cd*GD${U7SsRYrWDqHw*-TMS;0EZSr#*{DW>k z9V{wC&nkYdgMXFrX+|hcagI^Acv4 zdCdF8puspN%zPb-KR*kJ)7=sSIqHmVfg>uiQM;!_9)$08(GaIiblkxxbf(cS_1&&K zY-pXHI)^0{-l^akm9US#)^q5niPGMkO*|>EL6z=`dhh1dd$Rd`R2}WIAqsWZam=(v z^sM*2S0(@Yd0*s5pVv(k2;0Zz@$!fW`2;2+rq?o#=}WASMU|cW(yE_oKd)cN_SlHm zd(BE=R}}&_3k6hu&0ZA}=+25<2G{ND9v_x1qAV+SdvCV1r@zWmJwC2VBGe@l$;aat zvZ4CJ|F{brd@aq#XRkMje&}GRxu8&1W&NQ6IsyD2NIm+YH6kKdmpIvsj#tuqhG`ik zLQ;#eTeE+f>s}BrvwhwZ;hqNt66QZl_^$}?3-oeMkH(wG;o+$@;3xBaY{$8O08z~7 AumAu6 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/fr.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/fr.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..236f807a7d9827fb81ec716beb96440b7ed950f5 GIT binary patch literal 9204 zcmds-TW?cG6ou!t`~%(&s3{U^Ky4qZ3Q|C*;!;F`s*lDo!C)NM&ZY2c^3!;$(jU=w zeY3JN=VFIM%86PO**=%K?AdEy*6hhYf8R{kQi~`N>|fb`X+suZtKZf`u6DRbsD5a?oIott~NF9 zzOE+v9UPB7&=Y1E=hkzzZWJ}j* z<;9Vlqx2!IOOr^ACMM}})szoCqFMAFvLTtD7unuve0uKa%~aQ19b{R*m;Nsag}(3{ z=Gm@g314b<@R$jKL6!w1_O*KBi>|L7p@@d3S>`RZd8O51WtIAQrC_|SXIKMRqos+) z#t!SK(tcCpEQB&>qKU2CW;^Q+T~z8j)7)ce4&3Q6*WI4lfyX1g=emxzZOc{!1{)e- zroJA7v5*baUS-Mfg?ai~_kmNfA=_A4<4)EH?Pwpix1*k{6#0$jjit7Rf8m8AX~X_# zKl)2|j9Ezs_LYyiek192^}I^I>o?{aXDuK())cGp$n=`2jw2gV+k(U2lAbX#z{D}Mr$LH39bdQvKp_v-OOcwx%fPTRkt+>>!@d8+H@s8?AhbC75Rxcw;Qqq&siKr zt?-n-ynjP75LNf}+xF%nVMK5n#EcGJZea ze72Pn4V%2N$+XT-5Ab7hF&g@)Psz*88Oaa_sZae7(eYcjl{4s2nUZXZHq5DM!yOrt ztO&1%$2WN#_A|{)XPy~WFa{#YlWZe!5J!$Si*YnUAM6Q=--fkW!pQPrP4*w`ZYqfx z*=)lZ1de&A@yPMcKJ;59C2wr8W=4Tba3jY%9CTaf7L{gR5h;EMAW?w>O?f%k1HE#%z@S$ess-#i#6f zffyFX-m&adF3Q)sm|d>gvYIi1l>LkQ>50Nb{*u_(Yay*av&RH|mGOr=(QFC}NdvTQJ`{c;hA7eUO zMu8U~Df@QEA!{&p+3b>E>Ma>KV%91yx-b2^;^rz*mx-Fk5)T=T8UdP$J=i=;QFi#} z!6dx8Y5MaxH`Q0>y$-R>XnmR$gD{)~-(oM;+}D~7dMwvaT^GbIS!r-?>Ml`B37+j; zMVo7c&cP>YOlEpiWMN!LA2rw?Yusx)=NnkxqBnkiCu@~j<)k(71#XMY*?=FEqcG7Fv!zoQMjGVJYcep0IW zvBLVw+Ut5I{?M$LpN$n>{3`D)WpF30vE8HasFQ85y|zH3>;0UT<6Wmm znz(^?E<^f31L?ONq*vPynRk`_JZg-}$w?E7^Ru6y(}P;X^IbocBrLL78)~9gEcA&i zk$Mi5fH+s_p4t_(`_j!Xiv7&*v(8{G_!w-AlQhfV^DdtNI8Tskd}h_nGPm^Rw>&Np z0Orbw6UB8-F^Kh_9)rCEJvnQF?{T8lKKUvvj@GX5)U#Vz4_O6fv!3nTaiE#^SVeo) zJ|XhRUVt_{|!pMDzkxbB{2wU+v$b;gc)BRXYq2P-&nB=hD-l~Cmujmf&YMMGIdxp5s6ipoj2cKN?&BY z%v<6J(aHP8=6}AFeKqWw)^7JaJyo14ESvwWc_`^%@W@L(#s=HG`d)rZC7aXmah5S^ I*=8I60=jA%UjP6A literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/is.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/is.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..665e273e4a16eaba2f9ebc56421d6e9ce75e36cc GIT binary patch literal 6772 zcmdU!O=}!S5Qh8gUokRK3?`CEdx-ejM&|o{;Ynh>aFV1KbQBy-B5(1u+;ZJ-*f$q!Xm8neiCZ6 zya-hos%@y2XW>-e^iR~f(9=j`_SJSb+zYqD?XVlZ*4r|S_098b{eGoS>?u1vUuwoJ z&C4Ny%P|dQXtet?lXRgcq;7P&GR*Ynrz+LP>DKC{)yEe)*+}DtcIK5K)N1ZX{ha() z!)T>BAm*nnHfz`FYr>9Nf6=^FYqI{SJr{bb!m-WqRoQ2zom#Cs2vb{sDQO;Tp%+gz z5{j+lE2JGXP=#|nBiqWP;*^|rDLut8=bITwJkzK@Bm-JTzsz2!1!P)1*Y?aR6MJW0 zwEXjCE@QBQp{?noOIzbYt))qxU%Qp$#cDwU46)kTMq5+8yPnp1;#?7jMrT-RY#}*c z=mQ$1ECg%V{}05$nAQFc&o$QVrwA8XbrQ~`3oOX-pX=90kJUpv>!O8AlcQ0aTM618 zYIpEr-w%b?LZ@F#hV9eug}pa6isxWkZrAAkCYC(3wK?-r^RfBLkoP^i_WaVYgAKrA zH+&I3G3JQ;@cHIFB7dP#eMHeHItN*L8A%)7h&}Iy`?dzMckQ+@%SVred<_kKNXrEw z>=A2Pn!E|=6Fb9Pm^J!~R_YwF*6F|!jd;sS((_h|r%!}DC%CnrkFJ4L*n30h^4nf(|h! z^6Qyo9Lo~H0Sm5-BO({GYps5_gq2w5wT(ne`MBahk`UQo2ahYs3R6UPuX$Hg-RUst zk$AJumgp#E2(HJd-Rt5RYvy6eo1PqfAp6z0@jj<@M(cA~&Xd8A>`5+%w=Km6DQ4m~ z9>t^gyD!8HDKQE>`lBqEoXE2vyqJ6tRv?bD6R{MZCo4?3pYtz$h5Udlvk>RNTPgow zK3+%;6S=6>D$d^Yl$z(!)MKz`X!u;re_qL}%FW)nEalyJIuh_M2vz#UugRtS)WZ!% zo{c&a!L5UB=3k?@l5^y=ptX-!fNo|E~j{mn&~v@{tEi>MnAD0a?EbrdSZN> zH~_BpSk*<0JPP!@0+26mJ+wUrl3><}Bi|}x;)aWCaO!!sjNqYVmjn4@%=`K{gR$Qt z{Wj=X<4Nz%ejrJw(hhi~d&xG}Vs+r!zjbq4$`ixBk>qP>Fy7LlXLjvqU;fvP;Ey}E zrg#tT=5%fNw8$mzq19Thvi5b-9w@tnTm5bX`rD}IllPIacFdq)6t6G+WY(POJSjhV ztRAxbBx$VOq}mD@Gq;C2n_cwfzL`}Zx92gDiB2RZ_ZrV5@}Ufx{pws_{)8^=S2IiJ zei)=x?dQUBfn4@Wbu~$IB)O|>I{YDg-`VRo>4vPEYHhC5J?TZCLuuY`8r|4J_CjSf z@%Gz1GG8=FGDfTJ*QV)@c1vZ!d-JgG^>s9_@Op)ZT$I|)`^TW|`b?}nQzODt!GU^G zrT17>VmIokX;*F~3welF%em`~O}pIRV!q}Q`+p6%uO&-&t#_*_-KvY<*?cxKc%%gV zSi#%oY$9bh8@ZHZ)OtKmajsmwwf;ig%Gop43)7yyhSvgzmRHom99~ORiaoW10(D}> zgP)%^kCi-?yiEto?{q83<-t$IPi?p(&7yx$k2S`aRd#*(_a5eM8DQ1b7VlHVvorl( LhCj7(^6h^C=UAW4 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/it.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/it.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..4ccd7affbab8026fec9f6f0f0ebdf2fcb48639f6 GIT binary patch literal 9136 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pl.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..9a0bc8b9f2303e63295daf83d3ffe7d032353e90 GIT binary patch literal 9532 zcmeI2U2j`O5Qf(mRVDsG?oKO0pdzh+%L>sXR25V$QA>n?E5~*dr;Z)@BgR(#b?<@q z*~zebj_o8=IU!V472D_R*UaoY@668juRkA!2cZZr!$6-ceIDyyC-lQu&nIE1H>aT+ z+IrX4oBc4;C+!D%+t;s-`aIOT2jNlpM1Rb7KdgtZ!l&Vhey@kG&wm|;W*F(sejL@; zueN5NYL=e9oByoQ)En07#@<8qrj2#S>Q{t`-gm-1{rW}E6OE?#EdDO^)D3Ud?!A$6 zq>)Xv^z^nHHS;x?y{EQ`dbPr#+LPpc%{UF;Nt+^ktG^FTtH;vGcI`vc?4tdeYgY{q z+YJyt5FUp@KtCd^E1Mh%6Z9yA@j=AgG`4|O(0A6D2`gQV0fReX9$P_=z1?o$CBJL- zv1VfKx%$oZonsMfHN#!?Vol^Qy!G`AdM6q=iI~JEyRoNZ6HGpqx4FO7=e;e-*bf`g z8u%@8oygysQ8)ZdTFs+3qt3l(y;J?}X>PbD z_hI_CHP1*s%?ihw;UM-IXddQc<$+`xs}*VS@wVE!;;l|(rWb1GckbK9B*q!cv!xkM zG}h)|F7^Xm-bBgZzhU@N&x?#1&UzoM zUa!>`8QFR6SpId^z&jH&!;0|bTY2?F-}oi1FsAYJfqWcqN?cv#OZ=A}aPKtwFzf;& zP4s50ww~sP(T&#!`fjQBEUw9zB1QrFF~Z{n^RYIJ#Cuxz_1%|jCtF8!#l}3iG8aP2R5oBrjT1$9>}NVbgiff3`w485x`gzJ9cDykHGNuP_i2z!=9)5 z>uO9>n)KAVoJCXCnGnJb9cffkGqz=C;w)Cnan=uav@;-r3}CHsB6)a&M96WZr<=5t z?d~$YH^Zh-LH=7P-e4Dta8F{)yGmwU&Au&yvjbPjdy`#{B*WQ))$qN~E4H=F2IR4$ zWc8c~@Tm3hO*|!h5vAW*l1q_`l{2c8yWMTnl@U35tG41al+FdalFhS7qy+KxdecC8 ziLbNBt!7a>chx1wmex04Eh6@EFHO?9$1nQrz07{!M?|>4k@F>V85(()e2^z>%pCP_ z*4Dq$&NEstZ<%GD>Gz_XzDqBqD{*X@KKY4*9-z)5VLqS7K|6ueX8|&6SdZMD9C@I4 zl9=00==4E*vRk~HT7l*K`8fd;^kXJHj2XP=*A^FHad-g!TFjD(YIfS7&X9a=J8U=Z z#Api-SnRg?g7E^<*trfnRVDDqh<(X0Ql???nNQ;9VdSINm&8uaZ|}mqVPlV?oOR*y z@?GIXMufzkRo?R5@o1ax(oOEhYMUd)|JUA~@JGZj*a79{3vO*P4=|O^rn_;Ut`q%u z>s)vQ(=f#>vW?-HJi;ZI3irqFh3@~7adK>9-Bj7D+PZ#Z=j-R3d=aC(54vxQy}^`4 z`7)|=OH(hQCfvRvS96~8^Gex<i}&IPxO_2(vJ4EyVK%B`^z%~z^+TeCuYL9CX*m~iS=L=XcM@5hPke5xbXm+< zm9g!|)3Keqs%I=BH0M*Rr4qqihMBY?$5?ClX`1Kd5^)xCiK?eGw>CEMik;;(RBJhV zQ|}|K2ucEi78^?s(-_!>z z_$aH>QM)U%-QsQ0O(VFh+g0$Jk4SMI-@1++r(%jPF5B_vr5(4Ye8*Sgh-kVBM=wgV z+EYF&r~K=~5Nxqid5itY%@?hk?B;XDPx{MQW>4<#okWBU;qo zvKQ{~>q2Rg&>7O|!oJUYvT3>QWVuS6)nmsu=p?sse@{0E&W9J@!=wsto_Ud_R4e;- z>tfkFh$`Qv5cAQuKAf1w8|RrE9#6goJA1~PBj!ih1QzSW|G$CkoY(NHGgTY;|4|7q Fe*?&oG5G)h literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pt_BR.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pt_BR.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..7a11a9ebd1b4a522d7935545745913b8e411c064 GIT binary patch literal 8330 zcmds+OK%)i5QS@Dn>32lkUvfXq0KI(C*>fD;Y|GI8ht+D$y)!%*n{YgJVo7h614{fHABOBR) z#tt;HXV3MQ_djTKqNkzee4??dcHJ)72X@6iwGVAuBUkLR*H2GvVDqw?`4c@IXy0Q! zjrD(Uy8A#QoH8o2XPV19PF!eSV@r(>?XsS})90mDGy8dYZuDtn&-6ZKBi~#r2YNHs z=&0xvXR!NN@0OaiZ%_3;C7)==WBW?lH1?%_yR~|vStGsO(=H?XrO1kuNH8oXpXkYL zh&_3Cs97`px-QeA%N@OOIcM63cUT*FQ+`(Y&dAN1k)&oeAkXJ6r zH+^||UouQ=tJrq0$i0-72O3@I6aG1tb=~WDU`x6-k`BA01xRY_iAKO)Q}hqdU(*;E z0RcyP9%~iotbOhF0x{1tKGJ*iXAU-CKkzn{Op9VO(13-p^^xX*-Fte^b8SWUmt%{4 zZfJ)?t;O!>HqsjWgX~C#&t~?qKCdIok(W9yiba^m{6OSFE727BLDWRDbs=zKzv@J= zG%cq#l7h2YxsZj>aAYs^pD6Qa{ke<>3Xz!kL!ovkeU@4mv$3b66djr6XvFeuFU+-1 zWDBh4GsoH!jh9+IC>nZRK^Au5g!B`;`nm&+&Ls`=i0;O2*^ZFAV~_Qleqw#1JtHb4 z_gHd|)&2rO^HUFH3=IvOd31qUtb{gXfg?$q8sd+>;>j~6e?9x*m6?8A9*+UX4U!EN zRi0z;3ErP;9f$-4NIen?2Fgu%qZ>z=pI?<#xs&4yPh}?F*FIqx_Z0Y>*ze{1aXI6n zY~%U4OVexeWz++zPDJ%~!Oz=Njdo?iAJoFPs|lI+yKIDXbNLmdhS%KIc;JeCUg{-C z-&7N#)|_Z3YNuz5{CuS8lrLg>Ju)v>vhTjmjgfb9N5_a~bMz%wk>yVG)P*y4?I#w`r*G8pWN>8NOSu2|&x7QEY#Z1=sO4JuJ-)w!DD0R`f%IXayybv|E_Qpk6J?;?BfnUiSaS1z(Vo&c*Y%1zGx#zxOy2{fW8=)ZZHr$l z&TCmB!@R#(_j&{~UqyLsbMB9HMGpQ&uIA?Gx4n7EuvpUXqmh@L1#QYD{jr4epGUTz2D>Ah;`28jEyYBZrntv2XSlg&P3iY&tE~&1`RfK zXvpEtqx^o^=6TNTh>jD@?BaKf;%V5=AIhhGoA!NPXq@bYPUNqB`%O>W1mPRbN>;V2 z>v33@?o4zooXgPp<6cb1BYJ%|D|W$iz0>`|Cb-SNYe(^xq^Cy*Mv~3cquA;qPH${i zHjm!cW?ArWSM}~sMmlW!>VQS$M2Dx&G_W>)Qtq3lT#vr1*S@yg&i6iQR%L%ApLnm; znIdR|1A0uclXui+%5L0Kk2Mn5@>;|>V2OD3(~l)vVr!?Y$_{a8R%^7bPq3)X`f!)J zcx`TXvYxYa$rWLrO?9%ZP1t!ohUwYUTkMMEJ61=tf9fZmzm~s~kD!%z{l6&@o*ntb zX}!W(19)RTw#htu(HO1eqSLs3k82~eUg3IoM_m_6H~W>iC(63~dUwUI{;Brs=3S|a zo6vG^Wmo@H@A}_m{|9!r%2@uXpOe57J%a33)ZVIV&qLK4dY|p@bn5wi)}(KBL(1>J zf+Z12a3m@&jL*NRfD54!w<@m@&JbY&b^e*_`>w{mFZ(hZbh6`E8G4`{$klJ&!*Bf) z?aWF)x&6IIvJYm{Ls+g_yG1mBWmtV=hx}$Cvgg^~$YdwDW?zZA9}Ck5W1yMN1E_7^ o3(opJhAM(3`ooahVyoD}GY5>0bAu1pXiD9(Q{9eG;vn(#4<}c6A^-pY literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pt_PT.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/pt_PT.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..497cd8303f629217eb81634a95a8baa77b01016b GIT binary patch literal 8652 zcmd^^OOG2x6oqS@U*SXyks^i&SR#}RB#I!)LqLRBdTb}L;_(djc!uQPMl2#0tRl9+ z`Re$ls@?5LLec{QS+={Yt8U%LxsSU2=O0(ol{83q)1iJx`aRHRlIH1H_eW`=k&`q{ zV~ve9vY(#nm*-NSD%1`Xqgju4`l`eY(DSoQ7$cS2KUEtFh>w z>T0I{;VbGxjj+o!&t7OQ&)D%;^9E_9@kzRc~(rRWu&DR6nP16%SkJ<3I)XJfr z%rrX9GQ}QHpXu33vqtH$o)^yNqIjCFNt!|WLf=d2UgLR@?4f2(_3T($fbudu6y1f! zkPuDrg^TC9vOdu*&xZQeJPx%E*>35n`GyX&(EcE=d8qqmc?Z@%(ir=CA0&d_RPwNH zv0hW;I$BdUhpY`-PqMV1%YqkV$G#9T5?AwdIon}B%e0bC#u`1=9kx7`C5#ZPby<2C zh)ZmQT%c|s4TH)9T_Jg(WLIP03ACK(dZtxKSL4FE1YJ)wKGkz{Xx*YMxI@oJ+8Zr` z9JG%ePBagk-_difYrNQ=#vyd}MBzwlO#@o+hAiL()M9~;bl*myQCeg?&KhAJ^8>x$ z4N2jDDEf2pwhgWG^ow={eTRAHfjD7*R*xjc6{)>nMTmUN)({ws01faV5C?Mie5F==rYg6 zf~!1UMqX+k+w`!qBDA1edkB0p&UYy~{3DG$(zXrDzDU1|*X1iq7Vn!R@CcRP^b1-* zIG)cn@#RF%iuYl?zP!(|m|w?LthLa`{MciRGB}&a2OY7n6*yUH9r#5WxSk3vLuCT& zv>kONM*f;5Hcg~I5VerpIx0IEsaV;(!sSTc(44IdlIPMa{LL~C=cPMmhAvI)%HolU z$afJVu4lZxNxs5+>YRwZ$ii=)jY_7eb3>QT3MM0thOKRZo%C7G-9)^z@=-hQIYLBc zB8T>An@ydOMM@mp$#qDZM^^RA*P$Xkapii0o2ZN&vBE?8;$$yl2Y)X96`ox9i>T1{ z?TZ!f57v=4B3Gekyg2e(-vxzZ`RG#7v-Vb~_JfGGlb6WStS*V(j`Gxt?=F3*_Q)Z8 z>m6L}^`{HsHPM?|37B9H{qczZn^*YE$Z5kls4GTsf~JQw-kMF&U3WHdKISyB z)W=!|>p?M2l3lsOvFM-7)^$`TFV?-Q&{&*f=@jfs3!EN8i$2+vx-BZfQ|a6NF?VFz zb)Zj$L@cOr_9oiKS;yU(a)$nUSsn?t^{tSGc<#JjPR~Ua*PyODvFmfKXlMDEM(H%T z5BE|r*nI@kd8Tn99wYTXuOua1O;A#5 zu6h(LoyYEj^gxwXbojROvOU)I$0ar8NS(m&9@mvbkHRr^A)mte-WosD)9z3?T5opJ zqTc*)(3IeN*~VRJ`ipq75pC}x9=X4`P+X!r&gm^M=4?f03{2sAhx@J{AOBjm zFVzeF<98?DX0I>rH41X;70!NO4+Mgc5`E7buQgwER@*1gF0?W)$zdv#PM}FS4Z4;62Pbc5$lvUm%M)ia*Q9IG4cDKWCg4`+RWahl#w>hpi>x^+t z68xCyVmbU0iZjLQp(+9*_v>l6;+cyNzrEyL&*nR!Qgbnzv+t^rscvY@U0v!Sa8x9W zTDW8|`XOg$vTnTuDtUuQKd64kbf8S?4A% NcyQZNboUB+{sNwhwI%=n literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ro.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ro.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..e90bdf598bdce59c27cc6419c131fd8f747da750 GIT binary patch literal 9386 zcmds--ELDy6orR!Rjzx3dSg&&TGW8rURD*j1yu+F2pXzhI*thzjuSZ!0Uoyxz$3I> z-z@LWoZ}M`8aY)_6zBNNo|*l#_Rs9eUw__A*HbS&Ondqq>T_2=qclx(ecw+ry?K?! zXCoz8`8f)Nk^0Pv6GrrN)CA{th&A zppl8*jc`BW<&rCXAwmwwc5w^Rd-JQpQMU_JizoNmg5x{n5fStz}JYE#%#oHga92<0EikdJcc2GsywdX|ONCAg3an?a^iuD~T4SIUp+Uc_2NL&$a;yNipk!NP zW34&LsNT>x&ow%XMWc>&`dVQ>?`yk{H3#h*9bgn6`9|NvHU)FWWRY>6H3A*+eyxYsYTgXr>bnya_W2ys@XT(@<3St0iMs^gz@&6lzxIS&piFIzr;hvn(<3 z+TLIU!Oci9%yz^^VDLcmz$SKorC(ytKrwxy(QZVQ7+w%zU6UI|id&H@tdm~$GO%QA zfS9s3c)^!!cl3^>w=y5t_WU&G2;ZfLb=f~M3VAEM|8|ZCr^!3*+!mSVbXle7xm!!0 z_10x;d&$8z(qg@pid>piXjrrFt*k2#Vm23IYy@GLDkuTxP*9^(Z_#2T*&N8rmjL z!wb|O%tBVz4$HL&JHhp{j9v2fj-IIbT>Ua0dDmH&bxW?9t8SSo7mYP@by=jJWq!Zy zsA!SbS+04;2^&U+u5Ec1o8egl*@BaYtwhXkS`lko|8$@*up$%pw7p1Ugxx?aUgd>%9>VGXQ2%lLx3kI_2Vqny~=);WKFsre}p zt{uO^J|CaA>}SMrYH;@Hid>v>>FR9f$Q%8V)5oNtRtNtPi(<9)>XZOBgyTql{+WPwVx|Tq8a&}_(9HzlZ(43rEBr;b9^&4 zg^c)V;NIDXz5?fA&K5+cvNv*5vrqx}R7lQQJ{58z1x@Z)bl0a|iJl%SK*>qpzFGG# z93jbquk}lPpqRu@;rp3pQQLqr zPMg%Q?qJ|C%TgHQU-p`E{3>bPX$JB5gpqAur22B#aHf5zeUJ1e5a#^G2_8h@=XBhl zA%6tIILX)j@sP5Xt}WXg@j-P5N0zPICg(5B-Oj4(Bw6Yj=p>xAWeROC`!n|zoB+H0 z`j=FDw!f{$x9`d7rP2X+?z=vb4eK0IkXz3v+Hg-YX0c|Boi}1@{>TN(=hZe|>lwlI zvIp9~PH$f#0zTJe-}?>w`de+^<55F)Jq|S+jaB`vUiDGBFVA-7CtFP$p3Z2ovcJ`{ zpXSUJ@d7>$^iys!rdr$gbUQf`G1`nPL?h=BvS%}{^mLx^-5e2-+;@;~AgJa_Gy-4E zZcJ^vIy*hiJh;Q+Jlc$}>=C%{$`BhZ`LGCmis*sGT>ujKUXObbc(z>N2Wsyz(=$;f zZUj98%D79UCmy5Fa?@db-PDTD_0!BK)EJR@$Sy@kPcsj3CmD4H{7`#vg9T@C&*WZx zS<81t%lYe;cKBVh$xTFdxI>B~eZI-OpS*_qBvcJWW9=KKQmsKvMsz2o)bsF0A8C}4 zOnnDG^*r}#c#FjD9o4d*F4rRQ46o-j^Qm2r$EqVTsVD zt7Ft!CE?ma+jW#G_q-*-lBvK{!7rZJUByN8j3@w4*gs-Y>7V-l7F-F&UU8yy^do-8 ztu&TqhVNAItf{=J>GAgRuQakJN}sy8>#}^*lJ?~~1{rgk>0bI;Goq#oKW=khZkdAP z_ut)>n}NEr?dKDfJ?6vi;_y^#+V+O`XP#Q#|G#~kHd@Q*G7h+H+tZz3blqzY?#ud6 zO+@4WFIYa;wmrC?slh%OjCsU2a5Y$*;ll^63O^-VI?L8o1l~Y?;+EHW+$#|w>D=&N zJ54N;+3-1#OcrbBn@j0atw!D^pAx(AiLR<4`WQiNy3Oktd8 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ru.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/ru.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..7afef95f4502e63c71ef7faf25f267eba0f0d320 GIT binary patch literal 8662 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 J7T$j^{S7y>vWNfx literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/sv.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/sv.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..16c3fb8425b8534245c8a2beddb7cde3f328d57c GIT binary patch literal 8600 zcmdU#TW=gi5QY1dJo5u45yn!469JD1#SU>0iW8!QfOs5xZD-~6uC*60`+x1fkVoKr zeYWYD*;(vZ9z$fso=bO6T~1Y@x`ge6=A05hvB}ie$)L-vl+dJ*M;u-;Y9D#Xylt{W~ny= zJ?%%G(l=Orpm#HkItcIeK1)8-iu3S9+7#h?{adfqSZ`USr=L>mqa{{BuF-Pc3t6a; zWQ^mAaab2g&clU%GZ(FXm5i3PC%KTgssWZR^%P$)Kdo;a$9l%wsur`T!*}w_J$a`q zKOaO*Hls}Y(f%_b$M&!#=CZH-jt@4M-o^66sN=EZK9Y8z54#k)w(qy}43vO@b6pQ) z7w}p2wrv7tPV~I5_odLun9N9(ROw8TR!x4mO=l1 z#MY&rVCxh$M@w6LSfU2R*xp^mi*q8so!<_G<*|PF?ljtg%!O^7L*}|dJA44LCYlH0 zzz0^xLZvK^wcBx$Gq7=BomriG*1(SBAHJEaMvfioIp5}a^2Kq?Rmb{XKjO0~*InDs zS-Q;{TVYG6qCyn1C)RRgZ%52sr*<^!6F$Qe*Q*S+_Aq|G-FlxF&hSV_ZrKRm##;GE z*Uc)B>r1XJtWACD601!ckjtyt2qe4KWeKMp%QR9fW3BC)B#Ck0Y2KQ5bY-2LrQUP> zZANC6FGcxktlqE4zAFo2Mc230D7UUu7^;D*O*^7kwHq{ioW7}YXVz9{F*niP@x;nt zl885hs;_K*Gznc=0&nphst|EYHOYD0+?6rNN;U86FZ>z441div+SME8Fpi7`uae!# z0Iy?CCj&eGHd%o=C)pY9onvx$X_q6tf#aAJkjF=|9B75flM^rW&8fbYBy;3&w<-}@ zQuUi0!*j`B$o#yup293#O|S^Ec7@TaJp&7+X1dnZ_aDg)ss2_y^epPJ1N z!yhpwN<|E4cT6OUgCq7~nUi-N1z8?A7qM!I91F-}ew(?f*>jyS{$CM}Hs;3g=%ib+ z_FdzcS*@r7i|Lwtc;YdnfF|Ior6`T-NrU(OrmD=4HN07V@sf zorJVg7)L2!T;`KEsjO5=M;-l`ycT-6ua@^&us(Vhbq?u>IEgiv8P$$aVu9Y>xAQ=B zyjaRmh;>}*9`51&hC2XRu4Y9}HpU;RXJMv8=MTm~_aOE9o>sUA*WJ|iA7mwZbRZ>j zogLY2U)DjYyZCYu-c{IJyBzCsSaN@-)pSagbKaD5`ccX}T_s!f-8*6oXyu@q5mg8fpXah?`EgcBPz_b#! zp2a7*L!2^0HG?+w+LJ8qT%lR&!?tI{yVq#9mH+&kK6!>23YK2yrKUc~+N+UF=brvz zTSWgDsxj@mZld}p`6u%eIDmWqZ-k|4MaZbF&j7t-&(zP$S=Ucb8(E=y#Mb4z4qods ztkG?F7~V?MwR!kO&BMN{dU!o^Rl+8@2ac5k~Ft-zVvf=QORV!>*h-!v3~wk z_g6+HBd_jE)HCSqS>&yDP5Cq|u@@o=-UK5t-}cFe&r;ZFxpMgQBB3tVj3@Hf?{QuH zMs%{`Kv}v}%_VbRy#}0znX@?4Uv8d(WG<2z(yUgip2ogHbyQO?&K2NVlUUV={_E8= zG<+u6IGfA*4YZcKBp3V=HV%3z%hWNurU?Qc_l^qQ_dfGdpV_3Hvqi zvlAnN8pqiZG3HYl?udw-haQC0JnKCm(qK1E^k9z6%043U*>^j7ktxXyOCZC+PtBz2 z4EbL8Eb>s^l1YhNRx>Nj95nAmVXchzxOd@A*sHKt{vX7iqyxFg%jq(HU*)T-W6b0J E2F9x~}hrI6rX%TzTVq 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/uk.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/uk.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..6f0e4db954c9d4570cfb6f8022b120c2c7ebf2c7 GIT binary patch literal 8644 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 TX)VFu42X*`Q);(H<+y(Uj`#>3 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/zh_TW.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/finish_installation.app/Contents/Resources/zh_TW.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..c1f7e85ed14a929123f59307c826e1b6a3349ae2 GIT binary patch literal 6642 zcmdT|T~C}v6dp(nLNVSLuQa?6TS!w_tcf>9OVQdkl#jCAPy%Fk*$-G2cImPo(D+3| z3}B5INvkoTiSc5u41d8Z(-`%_z@1l(H(rzkO?qL{^?7EP&b+%&P7CKI2#Xo{Ywk~B6vep(j3)6Nesp>mGki-z?#^H@*Z9UP z_BkSl`IuI@{4$J{Nz5kXo%B0+`XttJ*cB1uST~ZV zaAHB6!EGGzCjNK7)%M7-p4!h|=-Kjr-TPs0ORlO^4Ef?GuFNkzoM{)wE6b6*FdCpm!Fpb};Gk6wdBhKO&5gWwjDLhx&T4BN5F)KB~ zecZ1xlEp81Q_3I4`6eVwWS9GmliwY^`*vZ8|f|=#O#~M}jrPr_B41Rh!zASnglhy4GWc3bT%BT6M{4)aEXQXZ! zEfgk{9vx^Z29(95{}Cy)#LSL`sL#CAC;e{}zogBLUbU}KCpv;`kND#E^WFVoY(2J+ zzmPdKR^5JdH&yXqH@RCy>!bL?D5o*oAyIsgC{-Q_b(}g_3}U3&9@+A5`fms85r33! z&iDJ`)ZS|{{#LgaLnKG6oSHuyJjb!TvPb+ zN{+L5hw_9D%$Y02-TRDQvLz`B4#w!2r2AU-dW4k%nzEAmG zwnuKIzUm`udU+c%4`UJY8gfV){A1#n%00M;H(~To;G6jm^Bv|NhDT|&lw_KWWH`+~ zZP?c*V;XZFm5r3M2-#AxF>@#58xNwJesaPOH|v%=crEa7iz*}=;eAjEVMADJWXhsMr=^ok{c(sKA7XOmWsOK z$GxSMG2YayI>N@mlj0BM`M9>c&it5zk0RQ#2Gw4&7mpTX^kD^|YMn|JRUAwYb4_ z`kGZ5s~BBTcUla=u{ZVO+dv&FVOGV4kv9E{Q%CVeM+7Wxb-$m8_D%*?!V&ZhGzM8a zGBdEfZ3bS(KO_b-660o@@*4ZFffaz3krYI#oT{r}jXa!|8dVJ!H?YfbpD+ zk^7(F$akk8hw28iLM`w9*$l3F;5k>!H}_$e_ip%)`Hg;?0~*kO+42`}b;j3%_F1zl z-vzox-FwS3g2O|D&7+Pu2kud|u3dXGlIrTxyK37=qGO1=7efwJ*{YiN#tSuaXm|3k z_7u~t({beSJxkNCvGagphl DG=<}@ literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..59b199b762f3a862e4babc8645070116ed9b0b8b GIT binary patch literal 7076 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..a084b1938ba8032bcd02a187ec8c1bd8b034e678 GIT binary patch literal 10436 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 I*=8I60=jA%UjP6A literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/fr_CA.lproj b/OSX/Sparkle.framework/Versions/A/Resources/fr_CA.lproj new file mode 120000 index 00000000..f9834a39 --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/fr_CA.lproj @@ -0,0 +1 @@ +fr.lproj \ No newline at end of file diff --git a/OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..89825fbe89430ab556945422dfaa72b818f22690 GIT binary patch literal 7013 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 E19x9Hl>h($ literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..9a4cca0a0979eb30ae1ef02e06e4a62ae7e650e9 GIT binary patch literal 12780 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 LhCj7(^6h^C=UAW4 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c3d7a421fee1b17db3e1a888dacec7c19f7a762c GIT binary patch literal 7002 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..7cc884b0d5842f8922c40f424219597da21018ce GIT binary patch literal 10353 zcmb7K2Ygdy*MCMvlQhlEZkll~ORO?lHi$^s6j=g|dp8U2a=LjOd!F~S(Da0(W1E8H5l!EJFn+#Ywp9dRf8 z2=0s@#a-}YxGT;;YTONX$C)?>=i4G@gd1;}`J< z_(Qw`e}q@#kMZYtH$H$5;zRf_{sEuEzu@!uS9}Hkj&I<95JJ=>fpEk~l8J+ONK4Y1 zv?q^{&ZG-@jC3WvNk5WB1`#hAOoo!-#7{~{gha_iGKo|XMxG{9$us0x@*J5#W|5c3 zJn{-zNZulElNz#wd_+Db8^|YQBl(nkL3WZ|WH;GE_L2SM069cXl2ha~`GuS(7swUz z7x|kisFoV3iJEB&by62?OFPhx^bwjv8U2v1pdZndbQN7qKc;KwTDp#|ryJ-ebR+$g zenvOZ&Gd8n1>J%U(=X{)bSwRuZll}j4!V=>qPyuH`VIY-en-Ejd+9#9pB|tG=@EK7 zw{dx8Fn9uKkQV7sBGRKIWI!A;A`>zr3$h{`vZG|=Kq>HcAvf|2&h`!pg`y*}z1>6Q z<={EsM3Ldy-u{8&$Y5Wv(jO_{4DeI-D!By)$A0(qPlA3&wl|}w$RCLW3IoAFbW+{9 zT();`06K#Hyg+$zXaWqk-)H#!7mA4#3P%PvE(-c0k$hP&aWo@L&Awt=*d}(FDdGJa zyTZQQj|4bt1JrOB97vpz?HlW7lqp7db8{<-eNlf#&>xQOM@`TJs403dUtYHyMh%g_ z`XeJ@YGouE8Y>^N8pfp#i641CdKflnhMI#YEn;_V5mU(vwnS;5x~$5m56`hj~K42fQkJ(zbo^50k528LO6Fm+xSx`Teg|b0XZ>Ta{w{i&-MmC9o8xWm+TFa#(W+#4bcdAbu_?Mt)R+N>Le@#9LV?ZWV!jC6T>>C;SYt zk!%)w!iW(#-{i^ZY3-T`t)p!IGGf*_hr0j(`RnL{FkB^b|-n1u^tAnhN$14+M%V zk>r5iqJKB)`T)#_mod@B42%OawCGn^6e#xf4*S3gxtX$iPD9gSMlX<{8cjo~hhX6u z=y~)4dJ)Y;v(QUuHhNh+rYN?!t|+7U-CN<4+^M@S>I;TS#V&9Osf$^enNu+nvkdl5 zibVZmhZn)}pctw50D1-1H=+4x0h$R@^2!2He^y$HcJWtx#8GCIrF#v%9$&Q@y;fhm zw0DYno%^rh;IG~Fz$}W7yBbc;Xs9W>Ewl0qmK(X z3z#ZU*uOFw^n))*NE-^*pw(y%N(I1yzS`EhS9(3#fU@Dvde{TZb+q1{%|oA}&)~*x zmTv48G>Qp~Phd^tYtledz}Y5GZqo|9JzaA4^ww>`@mp0@okCxOyKh6=(GGC*o#6Nt zV5PBW7ut>Xpl{H(;PBt0y=Wg=j}D-N@Oc;=Dd0@m-U0q_AXFSE$^Qot67GV#@W_=CPlpp`mH zx8fY;+wgi8++6xHeQH<4^sJF70a{o?&`<-`m^I{fa(D=!2zYAHcjp2fM<>J!)Trx2 zFdAM)g+;t61NE|ren4lz5#;S;_xJ(*h<^H4?r{$N0{2j!vJ{<*`^JcXytmv@*Ob4a zOOh!cWXMVZ2z6lTbe9uo0WkC~QF!u?^ed?HJk{@UlY06>zfLh+l-z zUZL;=U%0p*5Z++}!u}F}*k2AD0~}5aFyKz&#mkqYQ7$lxp%UJUYrt*n5%!hlOseol zSoZ|hgLPvW8kPkIPlK&l8cRPcg^wJFfDk~i6T9H;L8aKvD%k{hPhw9<;TktU%~x^; z+z>ayjd2tF0B(vO#Hsip{4j2Yo8uO^B~D|lSZmgXwPo#Cd)9$WXAi|sg${Xv83ggr7w~{l@Uzj_nUnDOOEz1c2 zAl)U1;f}P;MJa*a$veZ8dpB+%_rZ!nhMaHQI|g9G8x04_OY5FDw&;K!z3NYhtE-~C zRHT-oS_b9x>QR4~#3Q9Bb8k;fR|7J;=iJ)~nAjYGe)DuG{rR_IWdt5M5;m-Jld5q6gr2+Gts93F#%agf8~AYKh( z18d`zAmdzmTI*VzYxf_;D+%ZDcoFAd|4DUlE(dUK0P~7C2eB}-v^*5{3F9EAiTZ?C z!tCD<)_e+2!3?5$i-_c>EO&sch^hD)DK5nsz0_NSr{ZU&j6nA4{K%L<#l46)13xcm zVhEedTxU2A&&0FvOL#VZ8PCCU@jUzrY&;(?z^~$k_%-}GeghTbxA5C&I9>$dcNDI{ zOYl;>3@^v;;`i|T5TE1>N~FmJoIBeKKpB?ea0$?}OyFL3d=^kr9xUB&I9Zl&qUd$C zi->j;n*-&tGlDZo_?b}|4Mlw8{UVM^q(xpPGXnf33fcoQ4r_Re!hV0bEQl?>RV>`s zE(!5mo-Cp{+_q+WCRV`4unLHy z1Au!}0(+mvCLXWL(6AnolRW$d-h#h`xVKegX?Q!{fkvTGkO}lG4oG<-D`rIrY_v$) z*eD}T)M(^g_n_v>@HY@<8sRj&7dK`;2r8{1pcF!|QPslofb8D)VqCfen?1{md=-&O zF=Q7D145A~*bRuO7#3RHJI5;O50asd5-_%dukG5%d65Yp!AJ2id|b+l_Tm%xBt8iz zI*Cu?GXR281_z&#$>3xefON2DL~Md2(a!=LN??8y0pfK4_=E|c#XsVo@XtW;z^|li zRdhI3!pc}F%!)BWNT$T_0*R(brZbCTgc@JK7bONMXX)`3s__MsD&N~n_&4w>X%&&p z)!<9`GD@w>?(tQ8Ej~oF`BHo}&fxBo8RP%Le*kXP$&A@p7K|mN09&<5Woyaxq@*&v z{e6>4ybeY2Ejg(q7(B?q%40bn*A)SF#Zo>(iGnEWGS-A-77}wiOTFB#dACro_&!1t z4bjGh2B(8`o`u=CdxZvKS(^!`$1Gki69&hR5{oD_v4hYRAaqm`8o0eti~~Y(KnMq* z-cl3@b-Htg6ylW65YJEbZt)DK2u}nwkTd}Hl|vfBE%A~@q%kTaO(1v6Crz=9q{3Y} ziS2M_3P>~3oU{P==oXqNk|hAQ9LQ@U6>y2mW0fm0(Gcw@XL=&30e=sOZX@#gP#8)P z;#4rXgovV7z=HitO2l$Q0-Fq^@LA~wRYM`wXN)@k!_!Dde)dq-WGSd*_T1W5-X*OCx9<7l>tL#7NK=0eP zyPJ~?o(zp?RYxFMySp+GCEZAO(gRH-y}%YvF~*)@dajQ5^dXt#anXBXn&&t+g>l2{ zRt4@#|4Dx_za|4AzkV9>>#0C5qCh0;)iPo!Hpu}q&Fq#ADR#UiPi*PW8PbHb79G;0 zS9*HKcn(hT$uKB_f&G?{eEHD#GlV@MEhBIP6mTB<~cNm$GzASU>N5>A-d80cXsjIJGleuWWp$Xp1Oge_pNjtu+9 z!WvorelRNBNj~R%vOr3X@en zIwBxayhyqp#x91j9vJ%uh!V4*TpI3l1jd=jQn8>)mXYP)FYl2sd7pehJ|rs&IG0qX z=?1a`ovAI?+$mNfvGJV6~WQ)$P64YGg8Rz5Nzfob-_sUX!bNiFZYA8iFO~NFy>{Q0uw`@*oxDUeqAlzmp$LcY6cCs?Rni^K@1o3>fW*{BCFa5y9gTktwyitC96($Fzb zQKA4KBLMxbKpFK@c$zSTyw5fRPHJJ(Vi12UFsU%W)*vuvOK|k(03ja&XcE9}5&<{9 zke+7IcBmoy9G+m^#fIe@*@uPG?CRco1Zf1p=Yg!FxTtOX2N=_a-1zzrq{Z zKp+cPfW!pSfSrAdnUWBBD4@`k=YuE~&`!|2a1LPo8&?|Ce(9 zlc!@biJz7vrc>!N^jSKMPN&b&8T5Jj0)3Irq_gNtbT)mN&Y^SZJo*ZqPZ!Wv=|cJ% zeVx8R-=uHRx9K}{5nW8HX$@UMm(pc)IenMDN8e{#+1G3v+s<~doopA|&GxWw*thIE z_C4Fn_Obo!06WMIvBT^LJIao+3a^#BJt2=f2>!a9?s?aa*~sxozBbZU?uE+s*CazTv** zzT>{<_Hz5U{oDcWAa{s6%pKv5a>uyi+zHuchfuFYF&ayc(l(1kTLOipC+JCl=FD#L zlg=LSe5ab85MdmWcZg>G;#g5HypNutKa9xi7JK9g4^n*$!+#}kpoZWSZQ&W_V?-bi zz@zniQbsD_5&C?xntTn9#Q#AtO@tfE!J}{swb5jF9PXkXD$s`XVcK4LB%VnJ(Gj$S zR?;WHMl&V-zYf}71&_ox!(;Eu^eX+G{z3nw*Xa#yK}UQu3E zA(dLisq892)kxJu)l}6{)lHSD%2pMrLaHZKFR13KUQsPjEmXa(dQ(-STBX{o+NL_7 zI;1+H`ayL;by-c+3bjg|pw_D0>W9?L)h*Q>)Q_vZ>QU-ab%pv#^>gYu>V@hh>Q(BE z>b>eC>R;5?)i=~P)wk5Q6NH3@35^q)Bs5J(O?Wt=MMBGjJ_%I`a}yRNtWVgPa3bMy z!rux1)TlL_#-y=m92%#_t>HBdG>tS(G)*;Wnhee3nk-F!%|MM;Gh7qUgf&w%(>1d- z3pF*G)tav~Uu(8&c4~HOE@>`nu4=An{!8=Un!hyHwVbx6wzoD@+gF>V?XMlE^+LU3 zs`e%AJKDwC8tqc;a_v#=kJ{@xsx#_bx(9TvbZvBPb?tQ>b&u#e>$>Q=>bmKA>U!%k zb%nZOU5TztH(D3eRq7V#7V2Kty{UU!w@6p5TcTU0dsp|q?nB*2x>dT5b!&C&bzka^ z>Hd*uPwbIcm>5lbIdN^`uEcYR*Yt_{2lU+_crS*L22o*7TFox0jo5g0cCEHSLE}O?D*wSsCY@KagY+Y?xwnAI6t;AMl8*O8@S+ItHrc+i?Xmr4yJEX$``z}3?N8fv+dphK?G}5MeVBcez0h8457@`p$J#^oarTJ4 z(muidiG7=WhkciQkNu$il>MUplKry%ujIsJW3nr`ZF1M-qU2!ml;mfVUrc^8`R(LI z$<@hAl2;^up1dXbtK_efw%$Bwm*^^Q**pE@=YVPJ?R>?#+PTKL z&bh(4(fOHkv-7a?f=lDlx%4iB%jhz@tS-B&wX3%)$Cc+A>Kg7E=^EvF+VzZUn(H~& z^R5?Nvs|-XZ@S)bEp{z&Epxr=+U45g`quTmYoF_Y>yYb+>u1+_*G1QFt}CuJdc2-oPo8I} zXP9S%r@-U$6nXrfQcu7$#xvFv@{IFDJe8gao=Kj`o+{52&kWBg&l%5I&rhCnp7WlI zo=cv~o~xeUJ%4!q^j!Dc@Z9v=^4#VzPkAM;<~6*I*YgJ6$eVd9Z|5DnlXvqx-+*t# zH{qM|sr@9`h-EBKZCYJLsB zj^Ds<}_B{0@E>zlZ;p|DNB+AK(x1NBCp>3H}s+hCj>y#Gm8O^B4I` z{AKXFbZbDD%b^w;1t{fFEkJu2~C8i zLaOkv&|GLKqzkQu&cdU@V?rMxQ|K$?2t`7f@Psf$m<0t{coDHM3om+B{*3<>X8$kX Co{=d4 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..285596b97849a66b90d8ecde36537468936b25a0 GIT binary patch literal 12716 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..4ccd7affbab8026fec9f6f0f0ebdf2fcb48639f6 GIT binary patch literal 9136 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 JjsIPN{{o2!YP|pe literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..ee41cad343b0a32417537de1ec561d08e3db8e12 GIT binary patch literal 10436 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 EA69arr2qf` literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..ebd5759b31563b6d218ff58e39074f1d63ac246a GIT binary patch literal 12524 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%0A+#U<`m0|()RPlW6p@4+(&3LXD zp@}qKMqnkTXa#P?x1cWn)D37|6A)YzE#i4NO^6op9jFN}#EZ176=ARsLPR%^>gWKl zcnD1p2(k*OUrGOBfqpy)VwvlK{z27TQWOSW6-dU=xL*usGGpNkUWy+Av))1emtzQ) z{#hm-#gE~~MVWXKKLrMCFwLbo9eFlgV%q;N&n~m;eKx%(DT#O{XON5SsNkVn)?5#Lo@l8&|m?*ug&8t^v?7VT-gLsDhY zF+tAt3mS`e3t1Q5gWty=;Jpy2O%WUuxTZt+F#ZrcbE!96?~B5NBz#~?AvCH57fp-l z7`f<^x`;N3LM@3FIfk5*w5*y-nKP$*mS9|j^JEGK%j(_IGO@ZY6m!V~Br1>L<3MGs zaV0($L+9VTo|{#MLaAcJ@v-WlWbEbDbmg(W&(M*W5Vu{%J5LfOQQmS$X-Rs@2ySKSdyN|fPbsu&w zb3g6=dh*taOn1nQi*{AtS)*|mHV<|Oi*eJy2Nunk?Y?)RylJ3&f_qU>g1g?cnKJI_ z?lSic?kVnkceQ)6dyM;L=p}BCJ6QCKd-?;*-Q%IJ^v?%r*1{*5mIoKh7-g7a?) z&WW+eRcP%Hx8gLyig9aqT1Cx}RW*h~Q~Uv6yPfYamMBPqICe69h?*fZB`T6g)Py4% zq9sWr8EHuh(Gfi{5F;^>RET$X5eup$R#Zjo#6dEMlkmhvI-^NIrc@~sssPnoT9KzL z;tPxJehOrp1&~S>)PeXzMCuEJ!IK7;`XOlo-2fLRB*N{B2&WR7{XwA_BrY~V^k@(v z2_8)nG@mahZK;cmX-iSsCqo@f+D*`Ph;(4#@ujiAS?Uq%O<+`neZ^V-hSMjwP6>;VP6pDv|7j%XWaAw+9v9fUWKkwFO2tACatu)VTDU^Dyl6Es6hx{_|B zJ8aw|5)A_hv=%Ibw7jS{q$h#+0tk)OoWxNppc%?eFw`S{k1f=T)|LvCR?f-F6k-;4 zU)TfUTGAKgKTGMq%WImi?bm+1zz&xX3o$&Lvp8GSkBgtZ~*B!y%Q$V@RQ zLHmF(586x0Anlw)%0V>2Hpa5bf(CEBPc(<~zzm8Hx80H>pxppzA^>cMgG_@&aXN>6 ztzV5h?5>~n#=^VW6Gk$DRFWGyB#azK1C*=Cy|KwV+8gwaRb7){lgY#zJGO9W+DJoJ z95+)?#jB2c;@^%dW!U0jr-_H{Pa34dl5#jj7!DAmHwp*v350{%PjlywO}&C0zznG3 zkqC*3RuQUrq*!xk3?)+ybUC z0;X}MSfiQ|;^Kx|@CHO_(vG}-tW;+}1oZY6(14riO~8Q`jx=296eM$8+ST3aUUd1q z%VHwMOP*N}sDn@h(2|wp8S*T74x%3juf>c^D5250w3Si_e#GqsrJd=I)=ri5dlh*} zlz7RM$EGbOP<=W;R>PXlku_j{#Hr$9l-?@MTuatLKp87uhy$eDYB^bpx*WSgpZ_E3 z^Lny@K<$W#wIlM506eOK#f8jJ$eM(5{IEKIRIs7+E_$b&E)mK~biP6%nUT$?`!i$< zd5>%*+sJmZgWg7Or+3f=bRk_tWe^+WHZ}%)){>$T)$aGf;@OJDBGAAW6L z3KT2B7X<;VNQpQ}Ag7u$wXIh$wDj6ZnMJ;eQtPl_t+z4K6oBlt&RPTW9p@;l6eN6wk82a`qGTrw_kI1o5$h$V#EwNUu-l}52x2#$a=hdNw|H#!xb+D5~^&(amJ z_fvE^T?SFmRDT@=Jp-(fsi7vgDTz$at%3U%fI*1K%B5Za;UBvXGAV*nXLO8#F@b#b zm=4!x%NRXhN%f3>$7Kls%+vgMO{9+_gB$j&epu*(yN>avHm~@Dl z^8I3c+#7CQ&RD?wAh<$fY>Yj|jH^$+f^jezLT)Yb>gsN=f*mW|MB+d^h?#IBn+?CcfpVy#i~)~b@2dltW;KI#5UmE3 zpTTNE7zB6g!X;B!sA|IA`M%nKH|(neUO?f`YB zP|!7^sbe5wdYb9S^k)Vz1L=!&6@7`mO!F#dNOzyG=)|^15$B0@{s;(tv-qX5?F$Ur z4`;}uuSihlGsCVu#&Tx30O8fAlV*%$3MA7YB+)|jD%EM9W=1iinZmZRhL}=c?iA~` z(#7WGM&Rz{FHjbQ!hDl&fYl4@1_98v+ut4?Pf;e00jd9QgRW+3MH^E~nKEE%w#d}~ z(Dig}HD~+pdjeR%(SO+sID5w2}?d&lE8iWlcl9gbaT0p-`UU9~RLxozEh znfsXgL4yT0?4-Ntu4=9;U@zPViSh}SPP{d2LsBrg5ReI~Dt3#PiLtR@9{=lLNkJcG zHmv3>%p*hr;qU+wfm_{j2>TY2L1Y7%`wfs)Ys zVb;_4>12p*A`nI^;2ydeg3x&o_E_LXO~`SA5coe26$jytARB6+L!hQ6Ttk#XF=8)0 zB)*lvyn*cW1Ij{#*};7uWZnV2?+JEmBeO}&QN_+HIZY4JebPy`K+%_ZkJ(E1(*raQ zJgKLwAXpn{s`FizJ5N~$ITX;748$&Gw^$SxQtEu)6mL@?8o8|KE0{gZ`+}7)NJ;m# zBd)Lu;*$7PX76&LSSQi8Uql&RK}eQxMwNhbCAl7c2f_0?_}>qH!SBLP4CgdFK`bVH zhR&m85D3zSa{}O;05~TA&Iy2X0^pngI13|UIClq}g?kwn;7kOR1y6TgprR+J!2f~U z|MQIu@_&+t|MfnHbP_g0JPGS$dDg{tX1lQ0v0d42Y@apXJAxg_7OS(-ZV0Jw;E`GxQVsDgBIoPQRdE(zEm&{fd4~zoFmK@96jR2l^vDPk*8p z=+E>Q`YXLif1|(CKj@$IFZwsV)QV9nhB`WF#Y`(^TQR(xBcq47H@UaCx4Cz?ce#z+ zCT=sgg?o?N%5CGeb33_R+-`0U_dfRlx0l<;?dJ|~2f0JsVeUij2=@_plsm>9=RW36 za3{G_+-dF%_X+nY_Zjy&_XYPQca}RRvYnlW@}Hu4((~=ihNlE^fS80`$Swj0Uyvuc zE#dZKIlEBwqGIUftIKVB!)`x&H@kRJL0;Q?JYa3T6eBsjD`f|{>J2aE41rhFCV|md z0~y@XA;LxY{xB%Gfw?X%);3;BcleVJ6DVV3shCFe{mt z#aF|2Gl!T{%xUHm=4<96bBT>(6M>o8z{tM9#DT!TA;7$$z_<~>w9&w@VqlgBUJ`47 zSHEs$=d-u73)n^ME9`pqUG_A4p8Y#6KCWk6|G0s1gW?9q<;3O1<;RVPD~KBvR~*%z|2vae*{$bO1P@v8Wgct^Z5 z-WBhT?-xHPeq4NMe0h9Dd}Vw?{OtIa__^_S#6J?hBL0>5_3<0y_rxEGKNEj8{(@X7 zPnLI;XUTKr}Hde+yD$*1^6@wKy ziUP%G#TdmnMX91(QK6_*OjJ}UsuhijX2ng4n-x^CK=GjBNyRF~TE$z6t%`k$Q;HuH z=M@(ezbGyyq$Jo990|?@S3;MBt_j@}`XmfY7?dz1As2GjyAzfstW0<#VOzq%gtG}3 zlrp7UsZy$y8fB8wth6YtO1sjj?5E6C4pk0Q7AeOotCW+KHOe~W6y;*&!^#!Pmz1lO zYm{r1uPN6nUst}Vd|SCuxmmee`GInu@<6BFohmv-J3ZLxtxnrJebVW>P8U^rRfZ~4 zHAppHHAU5`dQkO{>QU8WswY%Ws+Or%s8*_;RXwkIRrRLoJ=HeV4%IHz9@YD*4^aWD)#I(e&iMsH@bI)ivrm^%V6i zb*uUT^;7C~>P_k$>T~Mv)IX@tt1qa3QD0R5uD--6I16Xx>|6%NbJuePTp?G)jpuya zG;T4sgu9P>fO~>_l6#I@!>t9aJ^&j1A!ze4?ho!S?ve&;7)_ieUc+h9HN2*WW~gSE zW`w3dGg?!osnOJH{F<=lX3YZ41DaKuO`0v5t(xtcotjTHUu%BRT+(*dW@-m$^R>gZ zBeezE(b_TEVr_-CQd_H?qrF4BMEjWbS?xaU0qr5}VeLoSW7?0kC$*=w=aS-*%t_9q ztfYZSlap$a>XLj(^-2Du=}Cd4c}Xjio=ti_>BXd%l2#|JNuHcMJvo}(n!GT1Y4UT) zFC?!@emVJ-omF~ok3^PnRR`1Lv#hY(YjLIBwa{1LpN7#bie2>>VDH}^`rGw`g(n%KCF-G zoAq<_E&93oR{gE|`TBeG%k(ekSLt8YzoLI#|EB(9{Ym|4{TcnI`p@-W>dzXmp^u@T zVSwR!!(c;>A4_ZS`G6I^9@fLHX1e?-ZN}7>@e&y>@oag zWQ{7L+Nd$68*_|##(d*2;|ODcakR0}=rcZHTxDEiTx)#I_=fQ<<2%NU#?8j}jN6Pm zjGr1W82>U}GGSAqDb18_vY8yFuBKk5L8cN@nW@S&%@i;NO*2h*neH{cY1(c&U^-;_ z&~(If)O6f*!gR`X+H}VBmFZX0Z>B#?f0-_&;#4LzF4dMgD77p#occ`a_SBQ9m(1~I zwb^90n={N#v&-Dg+}}LVJjgu6>@iO?Pc?_kGt6_%i_8z2mziHMuQBg3A2wfvw?C58 zjA_=i%(U#Z-f4Z)`lpRZD@mK07D~H0ZE@O?wENN?NL!lrT-pn1tI}RhdnIji+NTy` z>15GatQNZ^!@^rSTduQov-GeOS;{O8mf4nDEb}e5TNYaGwA^iZ*7CY#vt_U4kmZEs zXUm`I$?1;tobbowXh zpQV41em4ClE3&Gr25Xu%-P+kYz&gY_)>>%|T4!1pS)a1LWIbp-YQ1PnvFU9_TdFP1 zmTt4zhS_Rtb8W4*TW#}gx7!xj7TK2C9<#k|d)Kzfw#By9w%xYVw%hiF?RR^;y^}rB z&e>D!db`n{YVT>KQF*bm#!Ib;sGBf-(hk?7zYT1Sp!jHAIZ!||G9z2kMqn~t{~?>aU)wm7yrwmWt@ zc01m8>~-vS9CRFZ9B~|V9Cw^>oN}CTeCqhz@ulOO<7>yaj_(~mI(~Be>G(SXWh7># zW@Ke#XY|hKn~{?-EMr7QLB{Bes*G^PoQwxE9?#g2u{Gm^jDr~;J5!x$&UB~E>2Nxo zE@u~KS7&!;PiLkx+u7UM*V*4W&^gFC#F^_H>Kx`A;Vf{Dc8+ltJI6Xb&NAnC=LBbs zbBlAUbGvh=bGP$-=U(T2=RxOT=Mm>o=W*u==PBnI=cmrkonJc7Ilp#(>-^sNqw^={ z&(2?+zd8SK{^h*HW1ivT_;_ByD|r>K<~4j0pTg^TBcIBr@#(yccktc#yZFWY68=8^ z0e&g}F#jn3IR7NSj9qTmxL!y9T>* zTzRg1*KpTJ*Co%^PuBEu literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..b21ea044d834951b1f87652cb20cee9a0ad9df42 GIT binary patch literal 7518 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 W_OwA68D3DD6JK<{^qKhYS^vM!aT!Pe literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..5da11e051e85226e22aaaa1fd5f3c71d39080c5a GIT binary patch literal 12417 zcmbt)30zcF`~NxTUWOTlVeSkt%)kJ%UZPw8MZqQ6)G$O8TvKp_5hsTkoEcOy@|aqd zS+=~DudlBO+GeJfrj@xXuBGOZOWC5CWt;8!mjCD6%OGmK@Bj1p4IkjnS)cQL_UGIQ z^u6{(3#a z4?MS8ha*uWQleC3M-Fr=>VmRRe>50Xp;|NvO-GGr7P=qJMUSC{=yCKkT7>?MmZE0# z0$PP$MX#X^Xe-)=-bY8#N%Rr=1bvDwpl{KSSc7A+6+3YW9*l?LVR!_-3wv=0Ps8`( zCOjKIf*0T?@RRsyya+er7x8NRI^KxiM3HzC-io*3-MAI+!zb_u_#{4qKgSpF7x*ju z1O5?T!T&)k(JS~5f(RxG5=o*-I=Pi}Az37w^dNbpm<%E#$tW_KxX1)@HlMCb$`I>xBekNDQe>f$l;-WY;r{`k1I4*%Rb9SyX*PYAedT>3t9Ih94 zJ6FW@=LT>Cxl(QjSH_LxMscG#7dL^c<|cDqG!9jAK5i;^FE^W;!_DO$;TCX@a*uIq zxYxOL+?(8HZVR`S+r_nVU+{^12|t)G<%jTP{7`-vU(Q$X!}$^XNPZML%#Y^B@OSZJ z`Eh(DU&W8-UHk;Tny=yA{6xN%pTv9kyZOnym#^b}yq~YS691(LC*w_ z*Ar^&I9DhwAK`%xuY07&SL2@s!xR2u_+Ky7Mv^}e9O0<;x`M$mGGS~qB{Y&ArAO%A zSvZ15z@J%|pM@3l{UgW%=d~i+U2rHitJGEJrX1y~1Y`N|;q^7Hkh{zssPh29eqUL@ zUsoSGf}BW1Y3PVx{C z+fhH1hw@PYDx^x9Ohr15R?(;FBKlAIFS>%hM%UAgbSvFXchQ2QXaE|B?f_ci&>(at zDgg@1{SAR?H?XV79SnJVF2>xErR62A32raor=m&Jd=izSA*c-I4MoFHIjTUz(FimW zjY6Z*82A~>#2log(CziY+yMbVrb)Badu#H&o?2g>+Xs`XL&d(J zI}{uto59hg<^6pO!WtS))k>O3qiB>4M+sPU49FgjTtI#~nt-ZN4RWK2z>4yQ32dt% z>?@I6?zzWJ5uHdMqYHHyRSAX}Gcq%}ce3PUHg&Sh=$4t?$#>dCbMe}k{4 z(C_s#0N6>TXP^&6I|N5%s@A?-mYzol0b5KohU%z+YV<-L0$R02LoB63Dl8>K3iC^f z$Mipn?m;uqy+CFYx)04n6!^mq2*6I12!roT=}vY5_Bb6~~*AgLM6M(M|3;Rn!zXdZe9J&fj~N6-TFC_6Vh2V0jB&7RBaU6Obe zxaH+zn4R*-?h>$aff zlAN{+AY;UG)Ph!^=TSPGF<-KVthG)4WqMvjFSRjK65AE%Mf5WBYA78ffbo^d12cPW zCM@k5P$k6GxP#RJPd!t^_D$tASEDu14_xz17}5~(xc@gKe$1ihogDyfC0Dyc)(plB8BI%7soMkh;l2GfJA zo}DaNJ(`-%pzWXtJJ3$F3sm54Pz0tDyHP9J0}8Ph?Sr2KXdV204;?~>(UB@aUs?`U z)#I=6R2PG62d28bpdSSdp^)F#rtPuJYCsoQA~yqyDS*TRFzEfKGAhk0}kox_n>iB&iX zt8p|ihFNETok=O2DA>`S0S{QS#L~eY-(Xj*&odFMJd;}>azuGGNVwM>0Py6;{5r-* z5P-q1={JtPBRpDS>vg^KHa#LydOD2WM$7H}4#_N{B{Yqu>9BqXxW%?lK1GQA+Vk3) z=&iKO-tRlPTLK8jprRHyFOSu*TnR0s1*ZU-AvjJ#dl>o&$D?v=zzNuhO*j#-{2nL6 zPb#*6-d4*V37(4l)os?iV4!Tu?xc4JJnaO?r_;`~vrdI57*25e*oKOh;bdq8h8TgL z;hE){;ix585oOfX6Ix1r9L z-w*>#ZJ&I^>%T?;x40aa|CyImgR3G7zI2EkEY#dKU#1S(UD39hq z2$W5GP^(S}8LAX5;0ETv2WNEY#y(lOIoUnHmtPmG;Kuf7pr;%SXeUW0Y!3!xl<&hc zr5H`3`Wgl+FhwnR7QP>)|5Z2ObyG-iQ@n`h;A9pr;(4e6KaA(=c?-f|Ay`b;n;K{@ zuz3iLW&~Ln?$^`*7^5Heg=nS^(BHR8hz-HO8$!u29#2UDO=dWt!O!4l!LWDGfMyKg z(qBu(V*D?>M3Rc7_&G3Px6^!@*O6z0|8fK z3tod?L+K!E(%0)jS}%dL0YEAOkou3V4O@mVFmEwniZZ%nw?p#|-rP}0SKuvS*WIyM z(#%XyM=2!;t8vryyYG-h>`~Z#5bPcYnMAc5^WDHD`DlCaUQm=mucw~bwB>k@tjv;Y zf~@OjG!*Y=c^5u_58`+6dl0HkWUdLE(@}g39|zxD;R@8cL+~IAA6Qcej;g^)(;;-Q zQu0dal2xKmN1~Xsv3XTDfg18JcUmKmEpz} z_*593zoYXba9SUCpz}P?GE}LSzu0U;*)D>%g%u2avYrFC9N&p7$M}t7SN*!-MPzx!yve-l5VE|!bNANP5VEYZz#Jp8 zw9ebU{~_GIC=|7;Xv4Ge zKCdA7&u?4C)_P@j>s)yqa6CPL*I60aZLZ``d=&tcD;F|=f64%k4M(f2wL`3mlL;@y zs-0;iHA5yJEU3lLuFLAW;Hs0Jp`G-}Xh=saUhe$C^RL!V@Gf22m07VzOwt-9C9sLwHPE zTGBolYG3khOuHevfrUp_go9!%|`C(s%QX&?)Ou%UadB%=mNG|Dx z29Z9bFIq=ysh3WHdc-t33-T+7FFKTpNIt|h!$|=t1jUoH%W+^5DxtPj;i{z`I;kzo z1oeYjOScSWhor-0GLzH|YAqjiOft!x*V0T_8xl=YLI#7(3?XIc5D-@0mTHb8BS194 z8iq5;;yPEYTQY!iz}`p?58R)}(4GvbApmTHgWN48hq$(N;p-=59X>w1b^1`vP5Ckz zL+%Qnh@FS}Xx+7wfFa5129cY5k{T!U0=3i$=$8aTUly4I zC9^u_)k-6s$_h+zHx!sU7x=w3H-kKvJP-yM&QwVo>GW$Lhf8zW-K5j>WV(?17ve%5 z?O2xpae0i@CCC%xNs!-vkf#CZAUaGIv252LsB?KGNzvcYXQ*5^Km>GhCP?=TdJpg* zMj&2h;;%RA$nyTBW0T&8q+L(`MV63%lcf-=KsYRAP^{!d@1^(ACJ0re<(a}w^MtA= z$-3D>pvVN$Dx2Z(v}V$R(vOhmVa=uFMX(*xRB5p$O68d^la&zug^LZ+067W{2n5e90z@kc6oMmz>%VFj7{xzNuvw!qq`jC=7%F00Wew9i# z0dJzt&y%;v+hh}YhioQW=xjQN&ZQ5~2kAVj08gG@U+;BW%1Q@X>RnLOo8Wf^YAhjG z`dVMnfSdc`p|}Ws#0Ovn%cMz+oGKx)ZN1{cikl~8mbyn(So-^_UG>2RFJzlFmNI`Z z1OWk5&@59kyJX!wCq88;7rVpkSey&OqTdO+yWqfJfpWG~rA_LBpw z=1a=RLCD5?1AgPkd*l!cLs@Ye{)bcGe4nQdXbQ3>NS)nufr`%8Lu3!x$~93rD#^wp zl0#r;Z7ZS_L&PXE`2_hO%zc&&w2%|zBuejCZX~D4neY&1w^xwU;oxk{jCMaEt%g>T zvn{fVmuxPCTyjw_y9YdGcFzQV5;pr;xe$FpP?*v21A{t#&5#2La*mvrWLWk&74Euv z#*Suk4k(=_-RiUl1|$c?kuS+tU~vh3hCVxPqQ~b6PLeNKh0S?B{Giu2HU1U$71>{xWkaYw$|$&3^fo|m+SQbT#x9< zALLJVNkXo22(9A?S;TQDj*H+FTx6ACmPjgq1A&u;IDp-T`2*LkAcjbV+aNe%sGF6! zLX+UBZ8Yq=oIVG8FQH56zafH|6X1RXU|{jo2)P$P_{;A1 zxoGB)ISr@fbRb_{Cc|~tGA@QLTgC~rnYI9PA=+SejAjuq(> zGQeSY@n{L&RL;U#IU7_bmec3yYPy!LImS6SCns`gaKu~S2K83>?F5uV)nl;B2d=yZ zV4B_t)PO9&|x@3E?p%<*_-Qg^D&yaz6`<}Pbbgl$K}bUfu+1G@|5eU%ej26fGcb( zLP!blwN9zdDqloiYXt6I`vPS=D5N*Ids$qtt`7ihyRGfg@f5?QF(CE-ZP1NO9o5Fv zJGl~IYB!0guhVrDE-$SAeNO-jIQlnxLFWxSk-lsv(9H^NIP5eFb|Ul*x`D2_t8E`o zHC&>wKR0PM=_64&7G_s+RWN%R%zhi@ze(R>lp5Pskd?38?PCJR^b&Y+Q(IUWYq(lY z*UY)OiF6Zvrcr2L5 z|2kM!(1qOU)j|sQI8i|?(~H!>E$j#g>*kWaWHp%kjgS!(K(aE1ONEr5Rq{tcrE@f1 z%q{@XWqgTymF}bCA-b6Y;j#+uji*77ISay`6u1Fn`H2@I`{$uPz-s#4pk~<*Dq!r| zpaMz<2k2qxEdp*WveEsNhX}HR`+lEW4|*?x-P*uyl=4fd^LkFxL-e40lDD8p%e~EQ zqVLl8XaRWA^5Mn4YHvf0`ioA1H*tVn)4nL3h$E5 zA@j*1@;tmHwj169`w4=o+qf*QFV_#eY$3egHIN$w-fRdr3_Q(9Zan9Oce?7i`P@_7 zQtn02@J;Xr*Sp+F?i6>1JI`I_e&eq4O5kB<;9n;2E*tok3q0!!{K^Mj^#?u`^LN7A zUX}3fRs+13H4_ds8>oGmU(3JApW-j^zeeDQ^oVW|*%3V>aw2*~^oh7VB0r)qq9|f? zL`_6}L?9v*F*Ra(#EgiiBGyN2i+C^MWW?7IzbSZyPGL|O6^RP7B1K_Q*c54sT*V;8 zP{kO9OL4cNPT^NfQOs66qIgpAtYVeoO~r1-QNM~aUXpDNBNK39CL_&qW*QX82Z znHp)0yfrc_vS(yTWNBns3OCTUCTAL6xq` zQT0+4s`{%2s!CL)sxs9uRfTGVYLsfU>TXp~HB~iTb&qPcYN2Y8>Uq^F)f=iUs(q@H zsxMWSRNtt+Q(cbIMkPfhN2NwtqwG=6sI;hzsO+eoQMpmQqwa~C7xj45(x`P&TcZv} zeH!(R8mWmoQms;})f%-yZB!?!&FWNjmb$mPuezW54)sv=DD@ciSaqd(y!s*alj(*UZo?)I6d2hvsR`vzkSk#hN9WrJ7}$7R@V~^_tC^t(xtcotoX6R?Q*J z5zSG}G0n%C?=?SYe$xCB6BCmVo{GsE=gz8-Ky)S z%hwg^`s)VjhUzMH)jGG%r@KctSNFK?Mcq5PExK*G9lBk*k8~GwmvvY44t-~R4}G4# zKwqTquOFx{*59eG(2vkp>8I)E=ojdp)wk#m=-<^J(jV3z)gRY?pg*NQqdy;uV~w%a z*eW5>o;#*UA5#a73(Am(_kZUL~+-VqRs4>(TrW&Rj znhf&{j~kvdG#i#1o;SQ`c-ioZ;Z?&L!!g5Y!-s~mhK~)O8qOI$H(W?S3AqU+3BwaA z6UHY@NT^NlBuq}IOYkR5NeCv~pD-t3MZyaSFD1O3@Jhm~32PG8ChSf4(};}3$Qu<# zr7_AFZPXcKjXB0%#y-Zr#(u_pW1(??aiGyk zwVL*t_L~lxj+s6(T`>J_x|*m=j7u~m8WXLFJrnyRx)Y})-kW$|B2Ao?I6HA};)96~ zB|e-uKk=!=Wr;0`D-vHwd?|5d;;O{eiTe{TBwkH2CzT~lNt&1RQqtO_HAj@GNyn2uOFEx)A?ae$A7+JFZ#J1N=5%wmInR8jxx##xIb@z`ZZ@wpZ#M5R?=zn^ ze`r2y{>1#5`Fr#4$@*kd@-4}^$-R^NCihFuPac+Bkvt-KRPvZ)Z}NiVSCZdI-kQ8G z`9Si!$%m4UBp*#ap8P@bugOgx~ol?4{WTtda>5-C?GBl++#hcQYa$m}WDN9qH zPuZMuFy+gXODW%^e3x=L<;RqtQ`M=-sl8H*Q+=uRsZ&yesiD-VsWVgOr9PbcNa~}h z3sav+U6T58>W0+qsjaDdQ;(#cOTCzS#ll;R7ON%OGRQL0(qx%!X|`;!Y_sgJ?6S04 z_FDE^zO_bM)2+8zJ6pS2Gp*gM+17mP0Bfz)W1VcRv-+)5tU+sob)j{+b*=Rc>qhHa z)-Bd;)*aSe)|1xD)*ozfHiOM*OSGA7DK?AEX6tIpvURuhwB_1*+eX>O*v8r_ZR2ed zY&Eu-wkK_CY_HkY+1{{iw7q59Wc$+gi#@?^u~*q$_G-J^UTgQ*C)?}ne)|-A(B5F5 zW^c65us7Lf+Gp8k+vnOJv_E8@Z(m@4%>KCjN&7$S&)65)7u%QEpSQngf7!m#zRP~b z{-OP>{S*6__HXUq+kdeC~gd^_B!@E4m#d*9Cp0# zIOaIvIO#a;_|S3I@rmOz$9cyE$3@3ij;|fxI=*-O;P}b$i{m%P6~`Zrt4{3XoYBrY zr{6in8FV%{r#Ty)Gn`G%na)|x+0MDn2b~W&=Q|fTA9FtLeA4+3=QGYl&c)6p&ZW*} z&KBni=L^o4oGYEHoU5H{ov%CBJ2yDrbiVC;$GOG1&AG$5%h~GO>)h`==sYg=6m!Mi zVqdYJm@gKJ{l$S|v3RFASR5h_70bop;z)6{c$YX%tP)*fwdfXWMUOaHtP}m>6fr0^ zh||PIafa9=&J<^fv&FgMgW^Ntd~t!eP<&E+T3jS97MF-i#bsiPxI%nEd`Vm>t`b*^ zYsJ^a_2LHcP4R8<9dV1eP23^w5?jT+;(qa<_?~!Jd|x~!o)Axpr^OG&v*IV>XX1JB zf_PE+6K}jWT7pkask;y zK!!oaK^!cCC;~bvxQn>pK7t@13hs{MxZ=Js=e?H}D1Ls1FZAWUd(ZjrIsZBLoLd(S z1>=eA?888Sf(q220WDocSJw=fE5_o%NVsM|q;8hzPsFDV@WuR%K^(3ekcdPbK$dRa z&D{(-(8DFr9|pic$buZW3dVpR0w6*Vnji{upbeJ52G|U@LkDbuJ76npgFE3tcmy7W z$KXkL8eV|c;V`@lpTK|NGx#2UfFI#ELWq{=h>_TcgY+W3Nk4K0xstd@4jDtr$T%{d zRFFzCoy;I2sV5C2LZYOFw37Mcda{K4m8>Hh$luAWoK{ zI*ZPxA=*U4G(w|v4vo<`P0%ErOPgs6ZKd;Q8=X(v>2-7gWpp83L>JTR=`wml)qrp^ z6gmM0FoFrpU;!)GfCD=?zzIAEkOmh)59kTK@Y@G2hQ8Hq&*VrXF~jW{9SMig59pHk zbhl?>Fc7cyg_2_2%h~X!;v;1QC#Qao6I=0pPq(Mo?-%3oU|ld2OthZ6mUDZmgZLsO zP6>tsk!GBJ(eF(EeL*QmkyyNXfIsAm$7>Z}(riYVjy1C+o5TLbH27V|*0Z^XARYI5 zDfF9$8%6>a=UPevl?hnCVP*)}lLR48P5^rW&Mc`n_Mk`K8CVaSckC@m3gTVzE zRc;UdP*&zb(RRp#d>8@+PzXa|7z}56R?B8EFY~cRHk*Z6#bFo$BViP3;-LgaLn-R_ zM3OPTh;AqqckM*#lULV)Ki=d%3v&94drkRjDzto0cE&hB20n` zm<%4Mges_pDNqAbp%$jWbeI7%!3)=d59$!S;;_lc2`_iC+fx-6W98w57_0aB#qxyM zR2~q+iC}$Dj3E+ba%C_P5~t$6eJ!5gJh4kibx>@UhJ#^g*vs*q3(Dh@aSM@{WF?&K z@yA3ltf)-uoP#V#pr)?HNJm9miO)Yf7;ZqpQ!2|szJ_=g4%zic0ZFg??B(p8t2~L; zkT}5?pUsR6n2A+0j#U|0C7Z%*9Cbun0GOFsIpXDdw6(chd70_?Ij;81^tK_cg3NSR zeolM)q(f-SdT4+~RGt-2#1ICvpl1|d3I%4tY&mv1Ng&VK0<$0_lgK0g?i3VZmP!e2 zZCk#}rD!<9yPH2bgU;!{#2#a7bbFh9ahZV4qtdy0riZ@{?EQ95!IR-1> z2GqY2ZiH2^8rHx~$d?*e2Y*A()MEA+ErvqKJz1}p>x;1+3SpR!k2D1RzR-AIYb2Q{ z4aStrf&e|qs2G#b;&W-t*HGCS72{~dF=2@V0o=`)Kv0ev)|>UxvrExE9CO-<*i6InZVN6MXU$w$+Vb`ilfnxm_ErpHa+T#C&aplFBV8opq{hu zO3N;MC*UrEAyG;I@k#O`37ePem6BIJy7IzBF1J`ynLZ}$_eJB$5GIvC`lLuafkX~Q z6X|nZSveQ3=_{|PEH5idpPQGJec=SYtt}@vGrb^JW*ri6NM3vUG1!g{xeM-w9dHlq zgk7*3?uGmC-x~bh4-cS0C1=P^M~@VTf(=qukok^gEe;1U_la?72t6a>P%5&deBZS) z$Ds#|fOHP@tdE1@^Xqa>-2;2!A$S-wA~H|TKXPilm|ep9qR8?lUjy0-qfD|Ex?ajj z<^D)miG|1E2``6dfs#!-C3L{!kfBW22Tvh>S&9T@3+#jakdfk-GUXX~wsVRUDO=$g zcn%K0^N@k`k+u?xgm8iM4(D~n$MN&XoP-yV%rC*qXth^mDj$S8sP%G}xjmH_R%Jmk z6p&5VggHmbMCIYQn21*^)e0NH`sRh^g-Fzx^YBN~Zeu08NP_E$;t3(`&zJCpA`Q|jWQhEVWwL>smSwQNRC`)6Hk+m+MI^_` zZ(oO>P`(3xhF{=oTr#CGm=GsqXASB66ac4UnF_iy1UjX5z?p9Fh)RM-G^j5NwGBq{ zr4)4;GNp{@C1oYqkdjMG#4IP-E;dMfyaR_V#0nX>$6~oil19-w(jOTQ;fOuuCz(TA z3D-%_-(ete68?M!vOJcXViwXWEk&zB`QXVLT9}!h>-v3GEr1iGZzroTi)XWZg&19& zApOYzavA)m|ESAT&NugALnP>g>GLeXcWg2@qrS3c;#JlmZB&R4GxhC>%2< z8N?+xBqy7$d8y=tg+r(GQZeLf#awod=p3%6^9+8LE*d431x0K)9*D!(Rctu-yi^RN zVIn|2heR=!E{4+^F(D*;vBX&`k0nhru*%tocWq_`-j@T`mSv;Vw{yt0cHlDbY8poi5uSS5S zY^(y%b`HRBP%6FU!i}^s%cKiowv+45gE@{}(+wu3_xwVo7#xbMFKll=*`4ZSX*aSj z!+c*&ZXhdRF*PH*&zpgsu2;JqEa>1LGH#XqFHV|m3h0!Zn^((2kRy#v0K4YRqlHuu`Og5 zxfe2UJNT|^^lbmdfF}=-2Qe#9HjPc6mU4qT(mYHN{SbNB%V8C%ELTpoF4+%}NB%(e zLX`ak${vZbXR_%tQnJV67GlHBLRf^;p22CQIPF@T7KpebQh_4nrC~?0Q*@B$rEZbD zKwd<$y-e1USIDd6-{dtf*GC3cf~LS`rE7bsx(4eH%%78d38|q;%|Qk>usRlC^-MfO zq`;{qhh-ak8htS_AnOhLMFaCI`+tKR#hyv&6idZ=Uow=4ODP(UckHyckYnUHWc(p~0tDVbl8 zFHvScS!ReeNiw;V%!JfyOVXxxJ$0ATo|5td`4Oc!WGN9AJr|kp{AwMMbsLd;F7g|- z@8%rj3|>LhVDGpJYuT4z0dXS9+VKd_fQ6(A7Li8s3X9?W1Bc3bBkTcajy&YiI1HMh zNbX`}ZW(e4(=guCP$%?bai+#Zcuv!xc&me6)FGu2Sv~D3s|OzcDFA8^Kn*sqHLw`J z48IHUi{XK`mo7jg02~6~5CDe&I0V2U08S1aZbuJ(t6s!T39Qa z$J*F@*3PbD3m9Vy*&?=>UC)-VrED2n&Q`D+*h+RITg6thHS8v~mi?6_xItVNH<-)j zTwD&9%jI$T+z_sSE98c9!?@vG5qA|gf*Z+=;)=NvZZucQjp53;v5NhdK+$Gap*%0A z_RW$5@r0l&>5Uj1NLXrNJ`n@OsVm)sbPc^}MtMoCdcQDv)gRC%f)szTK;Rgr3h zYLu!(0p?)yvhls&7+o zR(GiHP;XOjSKp=Hq28(9t-epaNBxlc5%pv0qv~Voch#S&KU06FKBKW~dT1`y4Af+5 zT$&z>p-qdTa3NB5rY1Kmfu&-GMq()ZQ( z*JtVr^&|CV`ic5!`g(m-->hG(->!d6e@K5=e?)&&e_Ve;e^P%+|D&Oo;Yve}q0BJZ zFvT#{FwHQ-;5GORenX?7)xZoZ3^y5WG2Cjn&9K?9*RaoU!0@u+UBhRFpNx7VXLJ~O zW16vtv6t~uW0rBaakR0*=rL9qXBz8`vyIHS$auYRsd2e+qj9@&hjFKIkMViqLE}l| zhsMv1KbbV9fu>ATmT9obWy&?>n}(PsnxdwdDPfvxYB9|-%{Q$w-E6wWw9&N5wA=KW z>5%EL>4@p5>A2~H>7?nD=?C*5bBTG9x!&AjUTNNBzQ?@Fyx07&`BC%Z<|oZhnV&X4 zYd&Cp!Tg^2wD}kF84IzfEEth>e8*Fpga&3jSVYVXM2-_%IiLKOD zW?N)iV_R!mXIpQ(&332le%ph#y|#U}H*63G(0 z*zuL)wBuXH_l_SOKRbSPra7;4j&Y84mOIBeCpafME1Usm*tycV%DKk5*168P-nqef zuXDfiCFj@9Z=Bybe{lZf{KfejrgqA!c`dK!jl7w+@*MBrc|MKr!C%Vv=P%=P`69lU zzlNW~$N41R%(wDwd^^8@U&t@!m+;H@75qwm6~BgG%dg|t^Befh{BiyS|2BV$f0uus z|B(Nf|AhaP|BU~F|B64&f6IT*|H%K$|H_{ch@cWQf=)09Ccz@u1iR2n@Ca4H6k)0` zO_(8g1)ty-M4>?l3bTbKAtKBX;zCkr7FvZip@3Sp(NN?0ST71jys zg$=?j!bV|}@K51(VT-U;xKp@G*dgo`b_@3j_X`gSdxeLEM}^0QCxxek7loIESA;i& jqr!3FJ>e_iyEJ{8C9Sv8u2XCXqz_%I{O$Zd?c)Cf-}FVg literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..eec88ff179a7942b421c2a5e1de8d82a66fb5fb9 GIT binary patch literal 10333 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..ab2c86fc6f5392ccec7034379916e09b6cc4b7da GIT binary patch literal 12515 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..0646f3f2e64aa0ec0214ec688e0da090f366360f GIT binary patch literal 7039 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 gZ>GFV_CY|H>c!KT-JDxc~qF literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..9a0bc8b9f2303e63295daf83d3ffe7d032353e90 GIT binary patch literal 9532 zcmeI2U2j`O5Qf(mRVDsG?oKO0pdzh+%L>sXR25V$QA>n?E5~*dr;Z)@BgR(#b?<@q z*~zebj_o8=IU!V472D_R*UaoY@668juRkA!2cZZr!$6-ceIDyyC-lQu&nIE1H>aT+ z+IrX4oBc4;C+!D%+t;s-`aIOT2jNlpM1Rb7KdgtZ!l&Vhey@kG&wm|;W*F(sejL@; zueN5NYL=e9oByoQ)En07#@<8qrj2#S>Q{t`-gm-1{rW}E6OE?#EdDO^)D3Ud?!A$6 zq>)Xv^z^nHHS;x?y{EQ`dbPr#+LPpc%{UF;Nt+^ktG^FTtH;vGcI`vc?4tdeYgY{q z+YJyt5FUp@KtCd^E1Mh%6Z9yA@j=AgG`4|O(0A6D2`gQV0fReX9$P_=z1?o$CBJL- zv1VfKx%$oZonsMfHN#!?Vol^Qy!G`AdM6q=iI~JEyRoNZ6HGpqx4FO7=e;e-*bf`g z8u%@8oygysQ8)ZdTFs+3qt3l(y;J?}X>PbD z_hI_CHP1*s%?ihw;UM-IXddQc<$+`xs}*VS@wVE!;;l|(rWb1GckbK9B*q!cv!xkM zG}h)|F7^Xm-bBgZzhU@N&x?#1&UzoM zUa!>`8QFR6SpId^z&jH&!;0|bTY2?F-}oi1FsAYJfqWcqN?cv#OZ=A}aPKtwFzf;& zP4s50ww~sP(T&#!`fjQBEUw9zB1QrFF~Z{n^RYIJ#Cuxz_1%|jCtF8!#l}3iG8aP2R5oBrjT1$9>}NVbgiff3`w485x`gzJ9cDykHGNuP_i2z!=9)5 z>uO9>n)KAVoJCXCnGnJb9cffkGqz=C;w)Cnan=uav@;-r3}CHsB6)a&M96WZr<=5t z?d~$YH^Zh-LH=7P-e4Dta8F{)yGmwU&Au&yvjbPjdy`#{B*WQ))$qN~E4H=F2IR4$ zWc8c~@Tm3hO*|!h5vAW*l1q_`l{2c8yWMTnl@U35tG41al+FdalFhS7qy+KxdecC8 ziLbNBt!7a>chx1wmex04Eh6@EFHO?9$1nQrz07{!M?|>4k@F>V85(()e2^z>%pCP_ z*4Dq$&NEstZ<%GD>Gz_XzDqBqD{*X@KKY4*9-z)5VLqS7K|6ueX8|&6SdZMD9C@I4 zl9=00==4E*vRk~HT7l*K`8fd;^kXJHj2XP=*A^FHad-g!TFjD(YIfS7&X9a=J8U=Z z#Api-SnRg?g7E^<*trfnRVDDqh<(X0Ql???nNQ;9VdSINm&8uaZ|}mqVPlV?oOR*y z@?GIXMufzkRo?R5@o1ax(oOEhYMUd)|JUA~@JGZj*a79{3vO*P4=|O^rn_;Ut`q%u z>s)vQ(=f#>vW?-HJi;ZI3irqFh3@~7adK>9-Bj7D+PZ#Z=j-R3d=aC(54vxQy}^`4 z`7)|=OH(hQCfvRvS96~8^Gex<i}&IPxO_2(vJ4EyVK%B`^z%~z^+TeCuYL9CX*m~iS=L=XcM@5hPke5xbXm+< zm9g!|)3Keqs%I=BH0M*Rr4qqihMBY?$5?ClX`1Kd5^)xCiK?eGw>CEMik;;(RBJhV zQ|}|K2ucEi78^?s(-_!>z z_$aH>QM)U%-QsQ0O(VFh+g0$Jk4SMI-@1++r(%jPF5B_vr5(4Ye8*Sgh-kVBM=wgV z+EYF&r~K=~5Nxqid5itY%@?hk?B;XDPx{MQW>4<#okWBU;qo zvKQ{~>q2Rg&>7O|!oJUYvT3>QWVuS6)nmsu=p?sse@{0E&W9J@!=wsto_Ud_R4e;- z>tfkFh$`Qv5cAQuKAf1w8|RrE9#6goJA1~PBj!ih1QzSW|G$CkoY(NHGgTY;|4|7q Fe*?&oG5G)h literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pt.lproj b/OSX/Sparkle.framework/Versions/A/Resources/pt.lproj new file mode 120000 index 00000000..3c1c9f6d --- /dev/null +++ b/OSX/Sparkle.framework/Versions/A/Resources/pt.lproj @@ -0,0 +1 @@ +pt_BR.lproj \ No newline at end of file diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..e8a824aa575b735e80faba26740d1e607d75cae5 GIT binary patch literal 7080 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..03500fa909bf1778de61081d3a7a43e4ab5c1224 GIT binary patch literal 10328 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 F{C|l7Qds~1 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..dc92de651cff5fa7b4f194154bc040a0f08a61e2 GIT binary patch literal 12785 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c3603d55060a8c9fb95b1eb71c0d7b8efe5d4b33 GIT binary patch literal 7094 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%0AW?2 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 NcyQZNboUB+{sNwhwI%=n literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..d669654e5d8423bb7d919dfdd69c3112d618e631 GIT binary patch literal 7117 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 qvzRWRehSm?SS`V93NNfg}VksEB~5 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⁣zzW3+(NBM8`7x;_(#r{%%nZLqc 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 AOaK4? literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..e90bdf598bdce59c27cc6419c131fd8f747da750 GIT binary patch literal 9386 zcmds--ELDy6orR!Rjzx3dSg&&TGW8rURD*j1yu+F2pXzhI*thzjuSZ!0Uoyxz$3I> z-z@LWoZ}M`8aY)_6zBNNo|*l#_Rs9eUw__A*HbS&Ondqq>T_2=qclx(ecw+ry?K?! zXCoz8`8f)Nk^0Pv6GrrN)CA{th&A zppl8*jc`BW<&rCXAwmwwc5w^Rd-JQpQMU_JizoNmg5x{n5fStz}JYE#%#oHga92<0EikdJcc2GsywdX|ONCAg3an?a^iuD~T4SIUp+Uc_2NL&$a;yNipk!NP zW34&LsNT>x&ow%XMWc>&`dVQ>?`yk{H3#h*9bgn6`9|NvHU)FWWRY>6H3A*+eyxYsYTgXr>bnya_W2ys@XT(@<3St0iMs^gz@&6lzxIS&piFIzr;hvn(<3 z+TLIU!Oci9%yz^^VDLcmz$SKorC(ytKrwxy(QZVQ7+w%zU6UI|id&H@tdm~$GO%QA zfS9s3c)^!!cl3^>w=y5t_WU&G2;ZfLb=f~M3VAEM|8|ZCr^!3*+!mSVbXle7xm!!0 z_10x;d&$8z(qg@pid>piXjrrFt*k2#Vm23IYy@GLDkuTxP*9^(Z_#2T*&N8rmjL z!wb|O%tBVz4$HL&JHhp{j9v2fj-IIbT>Ua0dDmH&bxW?9t8SSo7mYP@by=jJWq!Zy zsA!SbS+04;2^&U+u5Ec1o8egl*@BaYtwhXkS`lko|8$@*up$%pw7p1Ugxx?aUgd>%9>VGXQ2%lLx3kI_2Vqny~=);WKFsre}p zt{uO^J|CaA>}SMrYH;@Hid>v>>FR9f$Q%8V)5oNtRtNtPi(<9)>XZOBgyTql{+WPwVx|Tq8a&}_(9HzlZ(43rEBr;b9^&4 zg^c)V;NIDXz5?fA&K5+cvNv*5vrqx}R7lQQJ{58z1x@Z)bl0a|iJl%SK*>qpzFGG# z93jbquk}lPpqRu@;rp3pQQLqr zPMg%Q?qJ|C%TgHQU-p`E{3>bPX$JB5gpqAur22B#aHf5zeUJ1e5a#^G2_8h@=XBhl zA%6tIILX)j@sP5Xt}WXg@j-P5N0zPICg(5B-Oj4(Bw6Yj=p>xAWeROC`!n|zoB+H0 z`j=FDw!f{$x9`d7rP2X+?z=vb4eK0IkXz3v+Hg-YX0c|Boi}1@{>TN(=hZe|>lwlI zvIp9~PH$f#0zTJe-}?>w`de+^<55F)Jq|S+jaB`vUiDGBFVA-7CtFP$p3Z2ovcJ`{ zpXSUJ@d7>$^iys!rdr$gbUQf`G1`nPL?h=BvS%}{^mLx^-5e2-+;@;~AgJa_Gy-4E zZcJ^vIy*hiJh;Q+Jlc$}>=C%{$`BhZ`LGCmis*sGT>ujKUXObbc(z>N2Wsyz(=$;f zZUj98%D79UCmy5Fa?@db-PDTD_0!BK)EJR@$Sy@kPcsj3CmD4H{7`#vg9T@C&*WZx zS<81t%lYe;cKBVh$xTFdxI>B~eZI-OpS*_qBvcJWW9=KKQmsKvMsz2o)bsF0A8C}4 zOnnDG^*r}#c#FjD9o4d*F4rRQ46o-j^Qm2r$EqVTsVD zt7Ft!CE?ma+jW#G_q-*-lBvK{!7rZJUByN8j3@w4*gs-Y>7V-l7F-F&UU8yy^do-8 ztu&TqhVNAItf{=J>GAgRuQakJN}sy8>#}^*lJ?~~1{rgk>0bI;Goq#oKW=khZkdAP z_ut)>n}NEr?dKDfJ?6vi;_y^#+V+O`XP#Q#|G#~kHd@Q*G7h+H+tZz3blqzY?#ud6 zO+@4WFIYa;wmrC?slh%OjCsU2a5Y$*;ll^63O^-VI?L8o1l~Y?;+EHW+$#|w>D=&N zJ54N;+3-1#OcrbBn@j0atw!D^pAx(AiLR<4`WQiNy3Oktd8 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..8022f52bf2338c7bcb1d2521f1e60cd07d6b144c GIT binary patch literal 7143 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 AI{*Lx literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..9466dc3ba5d2f4f0b761effa5e5f5445f9991de3 GIT binary patch literal 10524 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..7afef95f4502e63c71ef7faf25f267eba0f0d320 GIT binary patch literal 8662 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..e7d67a2bb407f5332f8a2073e1c0a3e69768644b GIT binary patch literal 12778 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 TPVE$r4$_C-uKZ2@?`-@ZEhtbQ literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c3bd6983fccd3ccbc25c5daff4d8a5cacc818b55 GIT binary patch literal 10232 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..1ff5bc35c9f674dba6f59a93b518ee8f5e2551a8 GIT binary patch literal 12751 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 ZxyG{sYLoCGtVRhR{ubqb?ALSq{{aOU{=)zO literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..7ec0bc27b08a739e4e882ba03ca30dbfe3f139af GIT binary patch literal 8778 zcmeI1TW=Fr6opS-k@D6bV5+8EM2gxzq6%n>5JJ!hXsbRBwh5CscI4bj9{SVUu5Yg# z&dk^Yi5jPsimXg#&UN4SI{W)d>~YmTHaJmL0s(VxExzV(zFuBkF?H#ct%2dT46iJ%(M>cA^(|Z zLOM{3o=57dCBbpX|C#!EZ(5IS)mF(m548eX_ZqB)7U1PgP=;^K(;a;;+N5o^@OT&! zVI1SLEgxzoUIP7<)}M;DV!K=FovCN8K6q@>iW~=OrGJ*zWk*=8bhNtSmr+3vh)Hk*brF^ps^Y_($a5j_uOar@FQ_Qgs-3(fw47??jh2$`~S(WBq@L?hBb=0$_+@=W@@I<|f*bhs7k?}i6wA1bi`zZ{3$c7sxT%JJEr z^z8<1SjCQ7kwA5(?;-`bhnAbY)^IE2RAl=hKeaa#SBNF{c*|s&?y!Yb`Lg3YPsi+` zq&N?WkwNT#wppkg%cC8`2H`bx>DAtV%#QU(EUjd9@YS^8qK}eQYzydgC+r13lr65I zW8UY|1v=r|nXLH0RmucSo`{A;4mZ>0`|L%I%#q|l*yVY0TsM!R2jZ#sY-X_MA&2Z? z#g~>z_Ok&J#9kd0omV!}w~^2L@{Tol#TN^G*{>IE_j-f&KHG8(JC8qF z8msfli*ZX-ZzE44Zo!gW-Y*`1%x}(T;5SEcFiN#X9wx4>QXXI%VkFprtUOb`F45a4 zoH57(d{OH^F#+V?Mrzo|G_cG(@?=Ih#EGqlf!|1MHSBV=|w271W!>&i6Xn15GG zU}Ul;^6kdFtgW1ZoA~-Nw3DM~663@O&5f?f~64O|X97|5fH9A*sKtHY$F3b7N z+{^r2r*iGe7@)tRVb8!ShM~)>-+oL0|70j?k60Aa02lP5SG<)u)RlJhbcKUC%p_{S zGoz?cV0}c|T8P2f(KR<$C$PR!o#|Rl)(17OTnjQ@qY}$LWYt`I{l0;qcwfz_{|E6! z%@nIDh;2)JfQ{g4eXYKd-3RGs`D(5h_S0giyQbyp0#yNLztu^J+T~CZ$^J&Q59?~i zrvt?$euefY(r7`vP0DjM&Up9BL7Vbd;>gu+DwXKM7HmJnHeIQlDUny!6n%Y&qZi`k^elTcQPeU` z8TWR%%2HqSY3@|0050?G$EoSv{#uQHKarja@}X|!TbUQ(@#V&(*ev;!IL|Csji$1j zW*o=q4<@W2Cc!2*c)A7@mj{VitasR4Fzt3`>wN~|4 zbJgdf=5p@-eo9Xpk?a?(N*o#~uC(=ic{^g0?Mh8s)5S)KL>IeXTNTYObP8 zr-I!WjW-{)@)v$Xb)@h`jf6@I_gt=&5gV`!;^SOxRUjzeK9Qx3otg-%FS^3@tC#`8 zeX9(}Z1ShE9Nz_J`eSzXWekKJQmIWm;Hl^j8RzUjM*D)sLs zGP7m-RB-;ACUcx?Dpz0WwM=e=Jd8azBg$-shj4;uS{GUcr4}plSq2aADF*+t-}-iK J7T$j^{S7y>vWNfx literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..8df1ba067c63f04ccd30f946911a1271505009a6 GIT binary patch literal 7022 zcma)A34Bvk)<5@V-*1xl$|{CUEK^EbS_+6j7m6K9D5Nc=EH!Oj+d!JsBrPpaxU3?` zqVnOwGPNKgD(H+N?i&j3f*>FYt_-82<2HV7pM2-Nmli1g{F(mJyyf0={`Z{!Irp4f z)es8C;%R9|fdB;!Xh8>hx|XghAJ8O4W5Gzcd_bgXj#M3wO&{QoR@Vjbamj#qq`?Jb zW!ql12@GI_E1^FOfWeRo8E`F(hiV9b1VN~W2DkwhzzVn>+TdTV)PnDOczrq5)lw`LtO|yL@s^9{GOw>J zh%Z9Yv|u<8nTNx>{m$^;7nFb$iN?wXREPYrScM8q9?dB?@OiwE-@rF=9e!`)|HGS( zfCtyw7y8Y>1<5nK{(6aPxVDld`ATyd zoKUV_O0n4}r7?z+)b+OGxa9JV)gOVspso}cf~ZmxByQt+Rp3xaLn}^djQervJ}JH( zhC(_dmwJ78qs|-#qjy0jWWjLAh7m9lM!_}Q$Se3PUdjEuj?d*`KIJHkfw3?SH3^Ul zd619#eUZj!wS;cSmtyf?7*`YtPxJbU{8ds2?PB8PeEJ#YfC88R*Fhot6(&LvOhOr6 zm<+`*1*U=zN}v?VU>cOebf|zCFcW6MY^a3m!4FjkUUk@1LcFb#O^A9+IZxy8X?*;C!i5NLf&tCqE8`<;Rsw=$KF#n~F<_ zL}e@CXkT?ylESLWq>eGjf;ejGoQ!l-wdMM&=LW;ID0o^)LC9Yl>%^hB9w{K}Rjw&V z@R1oQp7gAY*4E-9Xv-R?g*sH88jD8}2DhPSRA4Fv=D=Jfb~;F)jM@%!Af%AUr`&f4 zif~(rjJ9GyR(iUsR=!5Juk%t*{6d1BWHB6qa!p@5eKEHXqCLc_E+j9;}2L zVHIkQ!cDLm^{;`OVJ)nK^{@f?QVzGlM&wKdW{*566hiJPdMjBUjO|be!@MX`8?5$+ ziu^5+#&~`(s%91h=xc0{qB2^%&X4+QOIjMF7+P_BSmr_u zx06^+CKdl3Fk~m(33tI}*aBN&8yC39lXy4Yo%i5+Oh-8l4I#->?496g@Wx_?+myo#;UPUs$2Ct*l-c+c37^J1;n64gkj+}`K!!aoyD^sf#K7jW(@^qP#PGUFVW`-#uEeiuSBTaTzR<<0x z*{ZjWp}*dR<8VUp)=7-GQ}8}~0H-nSeu%lM12Y1~6<}aAM535$(S~wntBpn)!-2d= zC=$ix$k>!?msWO9Kc2=1@~im}ZgH`3fW^(n@Ckg13O|Fh@J~30hDcd2f8(?Qv}`+k0m<@mzJmY2 z*YFK|3*W)_@L%`=p((Ir;WCY6xV{G5A>{S>jR(^#HQC{&BKA7owGXG1NuLWbX zekM{xcAWC|9rzjLyWki26~4tO)9Qk8X;ND1@QzP5Fbz*p(VZvIA+;UOcY#MVGCZO~ zeW|EzD3ULssMC-MWyB~e%T0rXTw)fy7OOOBu*B`LG1DkXA_vT8&UP9)(rI(tn>-i{TXM)4?jt;%Pif zB}OMFNPjYb41{z2$6b|hzO^?WE<4}R#rY??#L60yOa{Yxk|IY6844AABp+eqV^sbV z6=>#&kuv{f`lrj6!*GNAfDD6OB$H&3;jo8f!!Zm233 zr5M0OfPBW9(eH^=*Lmau1o>!KlmqR7%P&@ly^Tm++J7q+#j9JDrq`d&{47Ql;XgC8VmuNoblp zG|gC^E1L$H+QlsXrdSB8-YLB<$5=;#9T;Iga;boizXW4?np|J0M9M(8e->j@!MKz( zUWD;F#F)<~s2Cj=VGJT=5=9qTz-`5s!)zssE`d3b|FsKD%=cL%l)X7!rv8Z5*3(`2 zPF8kd{Ee9O%gAc729}YvWF127gPgww>Ftd~>-`~xqps^lPm#%IabdR%d@>eelXwv> zB8$;VmRIBt1pFRmjeEjaZ^&c}Uf^c9#qYtbL~d~8veX~-1U)ra6~=>DucuzL znUhUi-o3qYLoqKHudX{n?gSUvL^fj{Q{c#%n|nD{yVxUFL>M z+>V+!JF~TtVUkI^_=AHkzD;XY!R{vaD>)$1mq_&ua&gv9c4JX7Pw7O}aeK&Kr5*7G zt0p&M^MaeK(gsJO+sPjC5G3Pr@LlKA3+)&OfjmMU#Uw%b3_f#4!Uf*Qyiuy?{p9gV zhDD`1UESn5W$!0X{DJHxDEk?dJr-rp<}+s{WEaUk9d!Z1QXF;whvnn2>v32h;*H4l zikzlK9mmGeMGnc$BYB0qinM#3+(ON zH;FOG#adp)1H6VyM~ECk738R5V_%&=Dg_k1;cCgmtJU?tOO9g;r8bWFQjNbc6pzUn z8+Ut5qT9&{auSmNV1!ambPTU#{V}sQN~1i=Pb~GKZXQ?LqIUG9%1d0_9}QB`ohD~G zywlYP+sTLIBN>|NysodiFrurS7t3}=$DAeqByZz>T#L>L@;Mx<77?yrL-ob{78O6DK14ygg0D_ z%ztU|j>x(^QCcwa8+GnwE^;1EB+9XsT#KdcYp|HOkz}p7qbI`>QVL5+9eIOC@i>B^ zvR(*#0GcBcc{CA&W+ak32bo)doWcVUJhq{3=*MGRiz)G<9zyk2JMGpkrx8Ux?V+d# z0smA0hF^}~CHTegK- z{1$#IkFy~xl?`QSES+VrVJwqnvEeM6jbJ0$D0U4S&8}r**jP4><*;0q$MV^DR=_5x z_Fn;`+xQgqdKGoH$qvLFg07)AV{jDas;6c7SpK)uHF6+f<%Rh~3gjeCcn{O{bi=H| z+{CdN?p1zH@SL{?^ut57EIbJtOTr{h?#2_)_Kix;4rEk)A===0D`ZfKAen)@Rm^4h2q`6X)rpeG` zYKCh@Xhvy9YsP5CX>v6_%}mW4O;i)tG-;YO^EHoaUe=t|e6RUUYtf3@6zxduRBb>T z)-Kep(r(di)3#~bwL7#swY#+UY46uQsNJi5Si4WVU;BjiDeZCX3GGMPFSK83f6$)S zId$E2eRYF%DY|ssXx$WDwJxliuUn>Dp}SFclWvV}o$hwsPTeluZruaAJ-UZIUyY(;V&luc>Ov6M&$k1%yhE;~!44Vx*4gWCgH#}i@%J8(|S;GOtVZ(=pj}4z1 z&KkZlQlrJ#$JpPPVjN){Yb-EMHqJ2C7#oc9jLVF>jBgu{7>^o{8IK!J8c!Kd8_yVj zGW9fFZOSken5LShnWmd&m}Z$OO@33gsm|15;-;HS8%%eawwSh=+Dwm`o--XZy>9x* z^rh)%v(e1VF0)`xGIuxkH1{>9ny)eEnWvb2=2G))bB%efnVXlImz!6bSD81PcbV@u zKWN@(K4d;@K5hQY{FV7B4(K^JMYc00cSevbDtXr)QSoc^Tvp#Np z()zUZS?lxG7p*T@4_aTbero-%^*0-_X>2;1!NzP?*sih-vyHOl*@|q_Y|Xa$wuQD< z+hW@i+cMj7+g95V+fm!QwiCAZZ13An+dj1YWc$V5+uq0SvG=w2w-2-rvR`e_u{YV9 z?epym?ThT(zSO?lzRCVK``z|-`-}FM><8_K?62Bix4&tB%YM$$*D=(Q=@{-9;kec@ z){*1LbBuRPa1=TwI&N`nbF?|y9XlKkI`%nUa2#;F?0C!Znd5WEcZ@OP;jO3qqm z&^gyx?_A)#!}*x=dFN}+H=J)d4?Ev+9&;Xde(3zp`MvW8=XqC8S6|m?SD`E7YIJRM zZFN2BddhXw^@$tY)U9>v-A1?BZFLWHXS++>W$to!g?pxZw)=W_%-!m~%e}?D&E4j1 zckgiTbU*7p?0!!mf=18@2Eim)1e@RxoPt{rg>FI*p_g!laHY^!=r0Tu1_^0GhL9=b z3KNB5VY`jHxWcCYDK+h6wRVlw2Mr1iGr9Ub{Bh!y~RGFM@$y0#DG{M z)`@e(kQf#l#Hbh-o5W^uzPM0aByw@7xLjN*t`b*^H;e1U4dSihMsbsPhj^E`McgK~ ziS6PJai_RT+$}yJ?hzjn|1Lfv?i2TmPl!*6&xp^7FNg=km&HTktK#e8o8sHzN%1}L leepB#tawiRCJB;sN!^lqCndT{imieCp|_~N9siS3{vUG~Ku!Pv literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..9ab3288239a3dff4e21465113c3df621c5e63859 GIT binary patch literal 10385 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings b/OSX/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..16c3fb8425b8534245c8a2beddb7cde3f328d57c GIT binary patch literal 8600 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 literal 0 HcmV?d00001 diff --git a/OSX/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib b/OSX/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..239b8f7d13e0385c6330f761eaa77facf2893990 GIT binary patch literal 10342 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