summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--driver/XScreenSaver_Xm_ad.h108
-rw-r--r--driver/XScreenSaver_ad.h534
-rw-r--r--driver/splash.c917
-rw-r--r--driver/test-apm.c101
-rw-r--r--driver/test-mlstring.c312
-rw-r--r--driver/timers.c1794
-rw-r--r--driver/vms-getpwnam.c129
-rw-r--r--driver/vms-hpwd.c75
-rw-r--r--driver/vms-pwd.h48
-rw-r--r--driver/vms-validate.c75
-rw-r--r--driver/xscreensaver-getimage.c2000
-rw-r--r--driver/xset.c389
-rw-r--r--utils/fade.c962
-rw-r--r--utils/vms-gtod.c31
-rw-r--r--utils/vms-gtod.h85
-rw-r--r--utils/vms-strdup.c25
16 files changed, 0 insertions, 7585 deletions
diff --git a/driver/XScreenSaver_Xm_ad.h b/driver/XScreenSaver_Xm_ad.h
deleted file mode 100644
index 371e0a2..0000000
--- a/driver/XScreenSaver_Xm_ad.h
+++ /dev/null
@@ -1,108 +0,0 @@
-"*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
deleted file mode 100644
index 22e213a..0000000
--- a/driver/XScreenSaver_ad.h
+++ /dev/null
@@ -1,534 +0,0 @@
-"#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",
-"*fade: True",
-"*unfade: True",
-"*fadeSeconds: 0:00:03",
-"*fadeTicks: 20",
-"*splash: True",
-"*splashDuration: 0:00:05",
-"*visualID: default",
-"*installColormap: True",
-"*ignoreUninstalledPrograms: False",
-"*authWarningSlack: 20",
-"*textMode: file",
-"*textLiteral: XScreenSaver",
-"*textFile: ",
-"*textProgram: fortune",
-"*textURL: https://en.wikipedia.org/w/index.php?title=Special:NewPages&feed=rss",
-"*demoCommand: xscreensaver-settings",
-"*helpURL: https://www.jwz.org/xscreensaver/man.html",
-"*loadURL: gnome-open '%s'",
-"*manualCommand: yelp man:%s || \
- x-terminal-emulator -t '%s manual' \
- -e /bin/sh -c \"man %s; read foo\"",
-"*dateFormat: %I:%M %p, %a %b %e",
-"*newLoginCommand: no-such-login-manager",
-"XScreenSaver.pointerHysteresis: 10",
-"XScreenSaver.bourneShell: /bin/sh",
-"*dialogTheme: default",
-"*themeNames: Default, Borderless, Dark Gray, Borderless Black, \
- Green Black, White, Blue, Aqua Black, Wine",
-"*Dialog.headingFont: sans-serif bold 16",
-"*Dialog.bodyFont: sans-serif 14",
-"*Dialog.errorFont: sans-serif bold 14",
-"*Dialog.labelFont: sans-serif bold 14",
-"*Dialog.unameFont: sans-serif 12",
-"*Dialog.buttonFont: sans-serif bold 14",
-"*Dialog.dateFont: sans-serif 9",
-"*passwd.uname: True",
-"*passwd.asterisks: True",
-"*default.Dialog.foreground: #000000",
-"*default.Dialog.background: #E6E6E6",
-"*default.Dialog.button.foreground: #000000",
-"*default.Dialog.button.background: #F5F5F5",
-"*default.Dialog.logo.background: #BBBBBB",
-"*default.Dialog.text.foreground: #000000",
-"*default.Dialog.error.foreground: #FF0000",
-"*default.Dialog.text.background: #FFFFFF",
-"*default.Dialog.topShadowColor: #FFFFFF",
-"*default.Dialog.bottomShadowColor: #CECECE",
-"*default.Dialog.shadowWidth: 2",
-"*default.Dialog.logo.width: 210",
-"*default.Dialog.logo.height: 210",
-"*default.Dialog.thermometer.foreground: #4464AC",
-"*default.Dialog.thermometer.background: #FFFFFF",
-"*default.Dialog.thermometer.width: 8",
-"*default.Dialog.borderColor: #CECECE",
-"*default.Dialog.borderWidth: 0",
-"*default.Dialog.internalPadding: 24",
-"*borderless.Dialog.topShadowColor: #E6E6E6",
-"*borderless.Dialog.button.background: #FFFFFF",
-"*borderless.Dialog.bottomShadowColor: #E6E6E6",
-"*borderless.Dialog.logo.background: #E6E6E6",
-"*borderless.Dialog.borderColor: #888888",
-"*borderless.Dialog.thermometer.width: 6",
-"*borderless.Dialog.borderWidth: 1",
-"*darkgray.Dialog.foreground: #CCCCCC",
-"*darkgray.Dialog.background: #333333",
-"*darkgray.Dialog.topShadowColor: #444444",
-"*darkgray.Dialog.bottomShadowColor: #111111",
-"*darkgray.Dialog.borderColor: #111111",
-"*darkgray.Dialog.text.foreground: #DDDDDD",
-"*darkgray.Dialog.text.background: #666666",
-"*darkgray.Dialog.button.foreground: #CCCCCC",
-"*darkgray.Dialog.button.background: #666666",
-"*darkgray.Dialog.logo.background: #444444",
-"*darkgray.Dialog.thermometer.foreground: #4464AC",
-"*darkgray.Dialog.thermometer.background: #666666",
-"*darkgray.Dialog.borderWidth: 0",
-"*borderlessblack.Dialog.foreground: #CCCCCC",
-"*borderlessblack.Dialog.background: #000000",
-"*borderlessblack.Dialog.topShadowColor: #000000",
-"*borderlessblack.Dialog.bottomShadowColor: #000000",
-"*borderlessblack.Dialog.text.foreground: #CCCCCC",
-"*borderlessblack.Dialog.text.background: #000000",
-"*borderlessblack.Dialog.button.foreground: #CCCCCC",
-"*borderlessblack.Dialog.button.background: #333333",
-"*borderlessblack.Dialog.logo.background: #000000",
-"*borderlessblack.Dialog.thermometer.foreground: #CCCCCC",
-"*borderlessblack.Dialog.thermometer.background: #333333",
-"*borderlessblack.Dialog.thermometer.width: 3",
-"*borderlessblack.Dialog.borderColor: #333333",
-"*borderlessblack.Dialog.borderWidth: 1",
-"*greenblack.Dialog.foreground: #00FF00",
-"*greenblack.Dialog.background: #000000",
-"*greenblack.Dialog.topShadowColor: #000000",
-"*greenblack.Dialog.bottomShadowColor: #000000",
-"*greenblack.Dialog.shadowWidth: 1",
-"*greenblack.Dialog.text.foreground: #00FF00",
-"*greenblack.Dialog.text.background: #006600",
-"*greenblack.Dialog.button.foreground: #00FF00",
-"*greenblack.Dialog.button.background: #006600",
-"*greenblack.Dialog.logo.background: #000000",
-"*greenblack.Dialog.thermometer.foreground: #00CC00",
-"*greenblack.Dialog.thermometer.background: #006600",
-"*greenblack.Dialog.borderColor: #006600",
-"*greenblack.Dialog.borderWidth: 1",
-"*white.Dialog.foreground: #000000",
-"*white.Dialog.background: #FFFFFF",
-"*white.Dialog.topShadowColor: #CCCCCC",
-"*white.Dialog.bottomShadowColor: #CCCCCC",
-"*white.Dialog.shadowWidth: 1",
-"*white.Dialog.borderColor: #CCCCCC",
-"*white.Dialog.text.foreground: #000000",
-"*white.Dialog.text.background: #FFFFFF",
-"*white.Dialog.button.foreground: #000000",
-"*white.Dialog.button.background: #FFFFFF",
-"*white.Dialog.logo.background: #FFFFFF",
-"*white.Dialog.borderWidth: 0",
-"*blue.Dialog.foreground: #000000",
-"*blue.Dialog.background: #BBCCDD",
-"*blue.Dialog.topShadowColor: #CCDDEE",
-"*blue.Dialog.bottomShadowColor: #AABBCC",
-"*blue.Dialog.borderColor: #AABBCC",
-"*blue.Dialog.text.foreground: #000000",
-"*blue.Dialog.text.background: #DDEEFF",
-"*blue.Dialog.button.foreground: #000000",
-"*blue.Dialog.button.background: #DDEEFF",
-"*blue.Dialog.logo.background: #BBCCDD",
-"*blue.Dialog.thermometer.foreground: #5566AA",
-"*blue.Dialog.thermometer.background: #BBCCDD",
-"*blue.Dialog.borderWidth: 0",
-"*aquablack.Dialog.foreground: #00EFEF",
-"*aquablack.Dialog.background: #000000",
-"*aquablack.Dialog.topShadowColor: #000000",
-"*aquablack.Dialog.bottomShadowColor: #000000",
-"*aquablack.Dialog.shadowWidth: 2",
-"*aquablack.Dialog.button.foreground: #000000",
-"*aquablack.Dialog.button.background: #2244EE",
-"*aquablack.Dialog.logo.background: #000000",
-"*aquablack.Dialog.text.foreground: #2244EE",
-"*aquablack.Dialog.text.background: #EEEEEE",
-"*aquablack.Dialog.thermometer.foreground: #2244EE",
-"*aquablack.Dialog.thermometer.background: #000088",
-"*aquablack.Dialog.borderColor: #000066",
-"*aquablack.Dialog.borderWidth: 1",
-"*aquablack.Dialog.internalPadding: 36",
-"*wine.Dialog.foreground: #AD8FA6",
-"*wine.Dialog.background: #2C041E",
-"*wine.Dialog.topShadowColor: #2C041E",
-"*wine.Dialog.bottomShadowColor: #2C041E",
-"*wine.Dialog.text.foreground: #706B70",
-"*wine.Dialog.text.background: #F9F9F8",
-"*wine.Dialog.button.foreground: #5F585B",
-"*wine.Dialog.logo.background: #2C041E",
-"*wine.Dialog.thermometer.foreground: #AD8FA6",
-"*wine.Dialog.thermometer.background: #4D2946",
-"*wine.Dialog.borderColor: #4D2946",
-"*wine.Dialog.thermometer.width: 6",
-"*wine.Dialog.borderWidth: 1",
-"*errorFont: sans-serif bold 18",
-"*errorColor: #FF0000",
-"*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\
- scooter -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\
- binaryring -root \\n\
- GL: cityflow -root \\n\
- GL: geodesicgears -root \\n\
- GL: projectiveplane -root \\n\
- GL: romanboy -root \\n\
- tessellimage -root \\n\
- GL: winduprobot -root \\n\
- GL: splitflap -root \\n\
- GL: cubestack -root \\n\
- GL: cubetwist -root \\n\
- GL: discoball -root \\n\
- GL: dymaxionmap -root \\n\
- GL: energystream -root \\n\
- GL: hexstrut -root \\n\
- GL: hydrostat -root \\n\
- GL: raverhoop -root \\n\
- GL: splodesic -root \\n\
- GL: unicrud -root \\n\
- GL: esper -root \\n\
- GL: vigilance -root \\n\
- GL: crumbler -root \\n\
- filmleader -root \\n\
- glitchpeg -root \\n\
- GL: handsy -root \\n\
- GL: maze3d -root \\n\
- GL: peepers -root \\n\
- GL: razzledazzle -root \\n\
- vfeedback -root \\n\
- GL: deepstars -root \\n\
- GL: gravitywell -root \\n\
- GL: beats -root \\n\
- GL: covid19 -root \\n\
- GL: etruscanvenus -root \\n\
- GL: gibson -root \\n\
- GL: headroom -root \\n\
- GL: sphereeversion -root \\n",
-"*hacks.antinspect.name: Ant Inspect",
-"*hacks.antmaze.name: Ant Maze",
-"*hacks.antspotlight.name: Ant Spotlight",
-"*hacks.apple2.name: Apple ][",
-"*hacks.binaryring.name: Binary Ring",
-"*hacks.blinkbox.name: Blink Box",
-"*hacks.blitspin.name: Blit Spin",
-"*hacks.blocktube.name: Block Tube",
-"*hacks.bouncingcow.name: Bouncing Cow",
-"*hacks.boxfit.name: Box Fit",
-"*hacks.bsod.name: BSOD",
-"*hacks.bubble3d.name: Bubble 3D",
-"*hacks.ccurve.name: C Curve",
-"*hacks.cityflow.name: City Flow",
-"*hacks.cloudlife.name: Cloud Life",
-"*hacks.companioncube.name: Companion Cube",
-"*hacks.covid19.name: COVID19",
-"*hacks.cube21.name: Cube 21",
-"*hacks.cubestack.name: Cube Stack",
-"*hacks.cubestorm.name: Cube Storm",
-"*hacks.cubetwist.name: Cube Twist",
-"*hacks.cubicgrid.name: Cubic Grid",
-"*hacks.cwaves.name: C Waves",
-"*hacks.dangerball.name: Danger Ball",
-"*hacks.decayscreen.name: Decay Screen",
-"*hacks.deepstars.name: Deep Stars",
-"*hacks.dnalogo.name: DNA Logo",
-"*hacks.dymaxionmap.name: Dymaxion Map",
-"*hacks.energystream.name: Energy Stream",
-"*hacks.etruscanvenus.name: Etruscan Venus",
-"*hacks.euler2d.name: Euler 2D",
-"*hacks.fadeplot.name: Fade Plot",
-"*hacks.fiberlamp.name: Fiber Lamp",
-"*hacks.filmleader.name: Film Leader",
-"*hacks.flipflop.name: Flip Flop",
-"*hacks.flipscreen3d.name: Flip Screen 3D",
-"*hacks.fliptext.name: Flip Text",
-"*hacks.fluidballs.name: Fluid Balls",
-"*hacks.flyingtoasters.name: Flying Toasters",
-"*hacks.fontglide.name: Font Glide",
-"*hacks.fuzzyflakes.name: Fuzzy Flakes",
-"*hacks.geodesicgears.name: Geodesic Gears",
-"*hacks.gflux.name: GFlux",
-"*hacks.glblur.name: GL Blur",
-"*hacks.glcells.name: GL Cells",
-"*hacks.gleidescope.name: Gleidescope",
-"*hacks.glforestfire.name: GL Forest Fire",
-"*hacks.glhanoi.name: GL Hanoi",
-"*hacks.glitchpeg.name: GlitchPEG",
-"*hacks.glknots.name: GL Knots",
-"*hacks.glmatrix.name: GL Matrix",
-"*hacks.glplanet.name: GL Planet",
-"*hacks.glschool.name: GL School",
-"*hacks.glslideshow.name: GL Slideshow",
-"*hacks.glsnake.name: GL Snake",
-"*hacks.gltext.name: GL Text",
-"*hacks.gravitywell.name: Gravity Well",
-"*hacks.hexstrut.name: Hex Strut",
-"*hacks.ifs.name: IFS",
-"*hacks.imsmap.name: IMS Map",
-"*hacks.jigglypuff.name: Jiggly Puff",
-"*hacks.juggler3d.name: Juggler 3D",
-"*hacks.lcdscrub.name: LCD Scrub",
-"*hacks.lmorph.name: LMorph",
-"*hacks.m6502.name: m6502",
-"*hacks.maze3d.name: Maze 3D",
-"*hacks.memscroller.name: Mem Scroller",
-"*hacks.metaballs.name: Meta Balls",
-"*hacks.mirrorblob.name: Mirror Blob",
-"*hacks.moebius.name: Möbius",
-"*hacks.moebiusgears.name: Möbius Gears",
-"*hacks.moire.name: Moiré",
-"*hacks.moire2.name: Moiré 2",
-"*hacks.morph3d.name: Morph 3D",
-"*hacks.nerverot.name: Nerve Rot",
-"*hacks.noseguy.name: Nose Guy",
-"*hacks.pacman.name: Pac-Man",
-"*hacks.photopile.name: Photo Pile",
-"*hacks.popsquares.name: Pop Squares",
-"*hacks.projectiveplane.name:Projective Plane",
-"*hacks.quasicrystal.name: Quasi-Crystal",
-"*hacks.raverhoop.name: Raver Hoop",
-"*hacks.razzledazzle.name: Razzle Dazzle",
-"*hacks.rd-bomb.name: RD-Bomb",
-"*hacks.rd-bomb.name: RD-Bomb",
-"*hacks.romanboy.name: Roman Boy",
-"*hacks.rotzoomer.name: Rot Zoomer",
-"*hacks.rubikblocks.name: Rubik Blocks",
-"*hacks.sballs.name: SBalls",
-"*hacks.shadebobs.name: Shade Bobs",
-"*hacks.sierpinski3d.name: Sierpinski 3D",
-"*hacks.skytentacles.name: Sky Tentacles",
-"*hacks.slidescreen.name: Slide Screen",
-"*hacks.speedmine.name: Speed Mine",
-"*hacks.sphereeversion.name: Sphere Eversion",
-"*hacks.splitflap.name: Split-Flap",
-"*hacks.starwars.name: Star Wars",
-"*hacks.stonerview.name: Stoner View",
-"*hacks.t3d.name: T3D",
-"*hacks.testx11.name: Test X11",
-"*hacks.timetunnel.name: Time Tunnel",
-"*hacks.topblock.name: Top Block",
-"*hacks.tronbit.name: Tron Bit",
-"*hacks.unknownpleasures.name:Unknown Pleasures",
-"*hacks.vfeedback.name: VFeedback",
-"*hacks.vidwhacker.name: Vid Whacker",
-"*hacks.webcollage.name: Web Collage",
-"*hacks.whirlwindwarp.name: Whirlwind Warp",
-"*hacks.winduprobot.name: Windup Robot",
-"*hacks.xanalogtv.name: XAnalogTV",
-"*hacks.xrayswarm.name: XRaySwarm",
diff --git a/driver/splash.c b/driver/splash.c
deleted file mode 100644
index b971ade..0000000
--- a/driver/splash.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/* xscreensaver, Copyright (c) 1991-2018 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. 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 <X11/Intrinsic.h>
-
-#include "xscreensaver.h"
-#include "resources.h"
-#include "font-retry.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);
-
-
-XFontStruct *
-splash_load_font (Display *dpy, char *name, char *class)
-{
- char *s = get_string_resource (dpy, name, class);
- XFontStruct *f;
- if (!s || !*s)
- s = "-*-helvetica-bold-r-*-*-*-140-*-*-*-*-*-*";
- f = load_font_retry (dpy, s);
- if (!f) abort();
- return f;
-}
-
-
-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;
-
- Bool whyne = senesculent_p ();
-
- if (whyne)
- {
- /* 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 (whyne)
- {
- 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;
- }
-
- sp->heading_font =
- splash_load_font (si->dpy, "splash.headingFont", "Dialog.Font");
- sp->body_font =
- splash_load_font (si->dpy, "splash.bodyFont", "Dialog.Font");
- sp->button_font =
- splash_load_font (si->dpy, "splash.buttonFont", "Dialog.Font");
-
- 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;
-
- 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 vspacing, height;
- int x1, x2, x3, y1, y2;
- int sw;
-
-#ifdef PREFS_BUTTON
- int hspacing;
- int nbuttons = 3;
-#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);
-#ifdef PREFS_BUTTON
- hspacing = ((sp->width - x1 - (sp->shadow_width * 2) -
- sp->internal_border - (sp->button_width * nbuttons))
- / 2);
-#endif
-
- 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;
- int which = 0;
- if (!sp) return;
- ssi = sp->prompt_screen;
-
- 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 (cmd && *cmd)
- 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/test-apm.c b/driver/test-apm.c
deleted file mode 100644
index 6b87c7e..0000000
--- a/driver/test-apm.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* test-apm.c --- playing with the APM library.
- * xscreensaver, Copyright (c) 1999 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. 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 <stdlib.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include <X11/Xlib.h>
-#include <X11/Intrinsic.h>
-
-#include <apm.h>
-
-#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-mlstring.c b/driver/test-mlstring.c
deleted file mode 100644
index e269a00..0000000
--- a/driver/test-mlstring.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * (c) 2007, Quest Software, Inc. All rights reserved.
- *
- * This file is part of XScreenSaver,
- * Copyright (c) 1993-2004 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#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/timers.c b/driver/timers.c
deleted file mode 100644
index 5aa568c..0000000
--- a/driver/timers.c
+++ /dev/null
@@ -1,1794 +0,0 @@
-/* timers.c --- detecting when the user is idle, and other timer-related tasks.
- * xscreensaver, Copyright (c) 1991-2019 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. 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 <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Intrinsic.h>
-#include <X11/Xos.h>
-#include <X11/Xatom.h>
-#include <time.h>
-#include <sys/time.h>
-#ifdef HAVE_XMU
-# ifndef VMS
-# include <X11/Xmu/Error.h>
-# else /* VMS */
-# include <Xmu/Error.h>
-# endif /* VMS */
-# else /* !HAVE_XMU */
-# include "xmu.h"
-#endif /* !HAVE_XMU */
-
-#ifdef HAVE_XIDLE_EXTENSION
-#include <X11/extensions/xidle.h>
-#endif /* HAVE_XIDLE_EXTENSION */
-
-#ifdef HAVE_MIT_SAVER_EXTENSION
-#include <X11/extensions/scrnsaver.h>
-#endif /* HAVE_MIT_SAVER_EXTENSION */
-
-#ifdef HAVE_SGI_SAVER_EXTENSION
-#include <X11/extensions/XScreenSaver.h>
-#endif /* HAVE_SGI_SAVER_EXTENSION */
-
-#ifdef HAVE_RANDR
-#include <X11/extensions/Xrandr.h>
-#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 | PropertyChangeMask));
-
- /* Select for SubstructureNotify on all windows.
- Select for PropertyNotify 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 | PropertyChangeMask | 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());
-
- if (!si->locked_p)
- /* So that "xscreensaver-command -watch" reports the time that the
- screen was locked, instead of duplicating the blank time. */
- si->blank_time = time ((time_t *) 0);
-
- 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.
-
- Now here's a thing that sucks about this: if the user actually changes
- the time of the machine, it will either trigger or delay the triggering
- of a lock. On most systems, that requires root, but I'll bet at least
- some GUI configs let non-root do it. Also, NTP attacks.
-
- On Linux 2.6.39+ systems, there exists clock_gettime(CLOCK_BOOTTIME)
- which would allow us to detect the "laptop CPU had been halted" state
- independently of changes in wall-clock time. But of course that's not
- portable.
-
- When the wall clock changes, what do Xt timers do, anyway? If I have
- a timer set for 30 seconds from now, and adjust the wall clock +15 seconds,
- does the timer fire 30 seconds from now or 15? I actually have no idea.
- It does not appear to be specified.
- */
-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 a client updated their window's _NET_WM_USER_TIME property;
- 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;
-
- case PropertyNotify:
-
- /* Starting in late 2014, GNOME programs don't actually select for
- or receive KeyPress events: they do it behind the scenes through
- some kind of Input Method magic, even when running in an en_US
- locale. However, those applications *do* update the WM_USER_TIME
- property on their own windows every time they recieve a secret
- KeyPress, so we must *also* monitor that property on every
- window, and treat changes to it as identical to KeyPress.
-
- _NET_WM_USER_TIME is documented (such as it is) here:
-
- http://standards.freedesktop.org/wm-spec/latest/ar01s05.html
- #idm139870829932528
-
- Specifically:
-
- "Contains the XServer time at which last user activity in this
- window took place. [...] A client [...] might, for example,
- use the timestamp of the last KeyPress or ButtonPress event."
-
- As of early 2016, KDE4 does something really stupid, though: some
- hidden power management thing reduces the display brightness 150
- seconds after the screen is blanked -- and sets a WM_USER_TIME
- property on a hidden "kded4" window whose time is in the distant
- past (the time at which the X server launched).
-
- So we ignore any WM_USER_TIME whose timestamp is more than a
- couple seconds old.
- */
- if (event.x_event.xproperty.state == PropertyNewValue &&
- event.x_event.xproperty.atom == XA_NET_WM_USER_TIME)
- {
- int threshold = 2; /* seconds */
- Bool bogus_p = True;
- Window w = event.x_event.xproperty.window;
-
- Atom type;
- int format;
- unsigned long nitems, bytesafter;
- unsigned char *data = 0;
- Cardinal user_time = 0;
- XErrorHandler old_handler = XSetErrorHandler (BadWindow_ehandler);
-
- if (XGetWindowProperty (si->dpy, w,
- XA_NET_WM_USER_TIME, 0L, 1L, False,
- XA_CARDINAL, &type, &format, &nitems,
- &bytesafter, &data)
- == Success &&
- data &&
- type == XA_CARDINAL &&
- format == 32 &&
- nitems == 1)
- {
- long diff;
- user_time = ((Cardinal *) data)[0];
- diff = event.x_event.xproperty.time - user_time;
- if (diff >= 0 && diff < threshold)
- bogus_p = False;
- }
-
- if (data) XFree (data);
-
- why = "WM_USER_TIME";
-
- if (p->debug_p)
- {
- XWindowAttributes xgwa;
- int i;
-
- XGetWindowAttributes (si->dpy, w, &xgwa);
- for (i = 0; i < si->nscreens; i++)
- if (xgwa.root == RootWindowOfScreen (si->screens[i].screen))
- break;
- fprintf (stderr,"%s: %d: %s = %ld%s on 0x%lx\n",
- blurb(), i, why, (unsigned long) user_time,
- (bogus_p ? " (bad)" : ""),
- (unsigned long) w);
- }
-
- XSync (si->dpy, False);
- XSetErrorHandler (old_handler);
-
- if (bogus_p)
- break;
- else if (until_idle_p)
- reset_timers (si);
- else
- goto DONE;
- }
- 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 <nat@nat.org> 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_quickoff_p,
- 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/vms-getpwnam.c b/driver/vms-getpwnam.c
deleted file mode 100644
index ec0650c..0000000
--- a/driver/vms-getpwnam.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <descrip.h>
-#include <uaidef.h>
-#include <string.h>
-#include <stdlib.h>
-#include <starlet.h>
-#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
deleted file mode 100644
index 707e3ea..0000000
--- a/driver/vms-hpwd.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 <syidef.h>
-#include <descrip.h>
-#include <string.h>
-#include <starlet.h>
-/*
- * 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
deleted file mode 100644
index 6cb73d3..0000000
--- a/driver/vms-pwd.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* @(#)pwd.h 1.7 89/08/24 SMI; from S5R2 1.1 */
-
-#ifndef __pwd_h
-#define __pwd_h
-
-#ifdef vax11c
-#include <types.h>
-#else
-#include <sys/types.h>
-#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
deleted file mode 100644
index 8f7141d..0000000
--- a/driver/vms-validate.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <ctype.h>
-#include <string.h>
-
-#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/xscreensaver-getimage.c b/driver/xscreensaver-getimage.c
deleted file mode 100644
index 092540d..0000000
--- a/driver/xscreensaver-getimage.c
+++ /dev/null
@@ -1,2000 +0,0 @@
-/* xscreensaver, Copyright (c) 2001-2018 by Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-/* xscreensaver-getimage -- helper program that puts a random image
- onto the given window or pixmap. That image is either a screen-grab,
- a file loaded from disk, or a frame grabbed from the system's video
- input.
- */
-
-#include "utils.h"
-
-#include <X11/Intrinsic.h>
-#include <ctype.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h> /* for waitpid() and associated macros */
-#endif
-
-#ifdef HAVE_XMU
-# ifndef VMS
-# include <X11/Xmu/Error.h>
-# else /* VMS */
-# include <Xmu/Error.h>
-# endif
-#else
-# include "xmu.h"
-#endif
-
-#include "yarandom.h"
-#include "grabscreen.h"
-#include "resources.h"
-#include "colorbars.h"
-#include "visual.h"
-#include "prefs.h"
-#include "version.h"
-#include "vroot.h"
-
-#ifndef _XSCREENSAVER_VROOT_H_
-# error Error! You have an old version of vroot.h! Check -I args.
-#endif /* _XSCREENSAVER_VROOT_H_ */
-
-#ifdef HAVE_GDK_PIXBUF
-# undef HAVE_JPEGLIB
-# ifdef HAVE_GTK2
-# include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
-# else /* !HAVE_GTK2 */
-# include <gdk-pixbuf/gdk-pixbuf-xlib.h>
-# endif /* !HAVE_GTK2 */
-#endif /* HAVE_GDK_PIXBUF */
-
-#ifdef HAVE_JPEGLIB
-# undef HAVE_GDK_PIXBUF
-# include <jpeglib.h>
-#endif
-
-
-#ifdef __APPLE__
- /* On MacOS under X11, the usual X11 mechanism of getting a screen shot
- doesn't work, and we need to use an external program. This is only
- used when running under X11 on MacOS. If it's a Cocoa build, this
- path is not taken, and OSX/grabclient-osx.m is used instead.
- */
-# define USE_EXTERNAL_SCREEN_GRABBER
-#endif
-
-
-#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 "../driver/XScreenSaver_ad.h"
- 0
-};
-
-
-
-char *progname = 0;
-char *progclass = "XScreenSaver";
-XrmDatabase db;
-XtAppContext app;
-
-extern void grabscreen_verbose (void);
-
-typedef enum {
- GRAB_DESK, GRAB_VIDEO, GRAB_FILE, GRAB_BARS
-} grab_type;
-
-
-#define GETIMAGE_VIDEO_PROGRAM "xscreensaver-getimage-video"
-#define GETIMAGE_FILE_PROGRAM "xscreensaver-getimage-file"
-#define GETIMAGE_SCREEN_PROGRAM "xscreensaver-getimage-desktop"
-
-extern const char *blurb (void);
-
-const char *
-blurb (void)
-{
- return progname;
-}
-
-
-static int
-x_ehandler (Display *dpy, XErrorEvent *error)
-{
- if (error->error_code == BadWindow || error->error_code == BadDrawable)
- {
- fprintf (stderr, "%s: target %s 0x%lx unexpectedly deleted\n", progname,
- (error->error_code == BadWindow ? "window" : "pixmap"),
- (unsigned long) error->resourceid);
- }
- else
- {
- fprintf (stderr, "\nX error in %s:\n", progname);
- XmuPrintDefaultErrorMessage (dpy, error, stderr);
- }
- exit (-1);
- return 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;
-}
-
-#ifndef USE_EXTERNAL_SCREEN_GRABBER
-static int
-ignore_badmatch_ehandler (Display *dpy, XErrorEvent *error)
-{
- if (error->error_code == BadMatch)
- return ignore_all_errors_ehandler (dpy, error);
- else
- return x_ehandler (dpy, error);
-}
-#endif /* ! USE_EXTERNAL_SCREEN_GRABBER */
-
-
-/* Returns True if the given Drawable is a Window; False if it's a Pixmap.
- */
-static Bool
-drawable_window_p (Display *dpy, Drawable d)
-{
- XErrorHandler old_handler;
- XWindowAttributes xgwa;
-
- XSync (dpy, False);
- old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
- error_handler_hit_p = False;
- XGetWindowAttributes (dpy, d, &xgwa);
- XSync (dpy, False);
- XSetErrorHandler (old_handler);
- XSync (dpy, False);
-
- if (!error_handler_hit_p)
- return True; /* It's a Window. */
- else
- return False; /* It's a Pixmap, or an invalid ID. */
-}
-
-
-/* Returns true if the window is the root window, or a virtual root window,
- but *not* the xscreensaver window. That is, if it's a "real" desktop
- root window of some kind.
- */
-static Bool
-root_window_p (Screen *screen, Window window)
-{
- Display *dpy = DisplayOfScreen (screen);
- Atom type;
- int format;
- unsigned long nitems, bytesafter;
- unsigned char *version;
-
- if (window != RootWindowOfScreen (screen))
- return False;
-
- if (XGetWindowProperty (dpy, window,
- XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
- 0, 1, False, XA_STRING,
- &type, &format, &nitems, &bytesafter,
- &version)
- == Success
- && type != None)
- return False;
-
- return True;
-}
-
-
-/* Clear the window or pixmap to black, or its background color.
- */
-static void
-clear_drawable (Screen *screen, Drawable drawable)
-{
- Display *dpy = DisplayOfScreen (screen);
- XGCValues gcv;
- GC gc;
- Window root;
- int x, y;
- unsigned int w, h, bw, d;
- XGetGeometry (dpy, drawable, &root, &x, &y, &w, &h, &bw, &d);
-
- /* The window might have no-op background of None, so to clear it,
- draw a black rectangle first, then do XClearWindow (in case the
- actual background color is non-black...) */
-
- /* #### really we should allocate "black" instead, but I'm lazy... */
- gcv.foreground = BlackPixelOfScreen (screen);
- gc = XCreateGC (dpy, drawable, GCForeground, &gcv);
- XFillRectangle (dpy, drawable, gc, 0, 0, w, h);
- XFreeGC (dpy, gc);
- if (drawable_window_p (dpy, drawable))
- XClearWindow (dpy, (Window) drawable);
- XFlush (dpy);
-}
-
-
-/* Figure out what kind of scaling/positioning we ought to do to display
- a src-sized image in a dest-sized window/pixmap. Returns the width
- and height to which the image should be scaled, and the position where
- it should be displayed to center it.
- */
-static void
-compute_image_scaling (int src_w, int src_h,
- int dest_w, int dest_h,
- Bool verbose_p,
- int *scaled_from_x_ret, int *scaled_from_y_ret,
- int *scaled_to_x_ret, int *scaled_to_y_ret,
- int *scaled_w_ret, int *scaled_h_ret)
-{
- int srcx, srcy, destx, desty;
-
- Bool exact_fit_p = ((src_w == dest_w && src_h <= dest_h) ||
- (src_h == dest_h && src_w <= dest_w));
-
- if (!exact_fit_p) /* scale the image up or down */
- {
- float rw = (float) dest_w / src_w;
- float rh = (float) dest_h / src_h;
- float r = (rw < rh ? rw : rh);
- int tw, th, pct;
-
- /* If the window is a goofy aspect ratio, take a middle slice of
- the image instead. */
- if (dest_w > dest_h * 5 || dest_h > dest_w * 5)
- {
- double r2 = (dest_w > dest_h
- ? dest_w / (double) dest_h
- : dest_h / (double) dest_w);
- r *= r2;
- if (verbose_p)
- fprintf (stderr, "%s: weird aspect: scaling by %.1f\n",
- progname, r2);
- }
-
- tw = src_w * r;
- th = src_h * r;
- pct = (r * 100);
-
-#if 0
- /* this optimization breaks things */
- if (pct < 95 || pct > 105) /* don't scale if it's close */
-#endif
- {
- if (verbose_p)
- fprintf (stderr, "%s: scaling image by %d%% (%dx%d -> %dx%d)\n",
- progname, pct, src_w, src_h, tw, th);
- src_w = tw;
- src_h = th;
- }
- }
-
- /* Center the image on the window/pixmap. */
- srcx = 0;
- srcy = 0;
- destx = (dest_w - src_w) / 2;
- desty = (dest_h - src_h) / 2;
- if (destx < 0) srcx = -destx, destx = 0;
- if (desty < 0) srcy = -desty, desty = 0;
-
- /* if (dest_w < src_w) src_w = dest_w;
- if (dest_h < src_h) src_h = dest_h; */
-
- *scaled_w_ret = src_w;
- *scaled_h_ret = src_h;
- *scaled_from_x_ret = srcx;
- *scaled_from_y_ret = srcy;
- *scaled_to_x_ret = destx;
- *scaled_to_y_ret = desty;
-
- if (verbose_p)
- fprintf (stderr, "%s: displaying %dx%d+%d+%d image at %d,%d in %dx%d.\n",
- progname, src_w, src_h, srcx, srcy, destx, desty, dest_w, dest_h);
-}
-
-
-static void
-colorbars (Screen *screen, Visual *visual, Drawable drawable, Colormap cmap)
-{
- Pixmap mask = 0;
- unsigned long *pixels; /* ignored - unfreed */
- int npixels;
- Pixmap logo = xscreensaver_logo (screen, visual, drawable, cmap,
- BlackPixelOfScreen (screen),
- &pixels, &npixels, &mask, True);
- draw_colorbars (screen, visual, drawable, cmap, 0, 0, 0, 0, logo, mask);
- XFreePixmap (DisplayOfScreen (screen), logo);
- XFreePixmap (DisplayOfScreen (screen), mask);
-}
-
-
-/* Scales an XImage, modifying it in place.
- This doesn't do dithering or smoothing, so it might have artifacts.
- If out of memory, returns False, and the XImage will have been
- destroyed and freed.
- */
-#if !defined(USE_EXTERNAL_SCREEN_GRABBER) || defined(HAVE_JPEGLIB)
-static Bool
-scale_ximage (Screen *screen, Visual *visual,
- XImage *ximage, int new_width, int new_height)
-{
- Display *dpy = DisplayOfScreen (screen);
- int depth = visual_depth (screen, visual);
- int x, y;
- double xscale, yscale;
-
- XImage *ximage2 = XCreateImage (dpy, visual, depth,
- ZPixmap, 0, 0,
- new_width, new_height, 8, 0);
- ximage2->data = (char *) calloc (ximage2->height, ximage2->bytes_per_line);
-
- if (!ximage2->data)
- {
- fprintf (stderr, "%s: out of memory scaling %dx%d image to %dx%d\n",
- progname,
- ximage->width, ximage->height,
- ximage2->width, ximage2->height);
- if (ximage->data) free (ximage->data);
- if (ximage2->data) free (ximage2->data);
- ximage->data = 0;
- ximage2->data = 0;
- XDestroyImage (ximage);
- XDestroyImage (ximage2);
- return False;
- }
-
- /* Brute force scaling... */
- xscale = (double) ximage->width / ximage2->width;
- yscale = (double) ximage->height / ximage2->height;
- for (y = 0; y < ximage2->height; y++)
- for (x = 0; x < ximage2->width; x++)
- XPutPixel (ximage2, x, y,
- XGetPixel (ximage, x * xscale, y * yscale));
-
- free (ximage->data);
- ximage->data = 0;
-
- (*ximage) = (*ximage2);
-
- ximage2->data = 0;
- XDestroyImage (ximage2);
-
- return True;
-}
-#endif /* !USE_EXTERNAL_SCREEN_GRABBER || HAVE_JPEGLIB */
-
-
-#ifdef HAVE_GDK_PIXBUF
-
-/* Reads the given image file and renders it on the Drawable, using GDK.
- Returns False if it fails.
- */
-static Bool
-read_file_gdk (Screen *screen, Window window, Drawable drawable,
- const char *filename, Bool verbose_p,
- XRectangle *geom_ret)
-{
- GdkPixbuf *pb;
- Display *dpy = DisplayOfScreen (screen);
- unsigned int win_width, win_height, win_depth;
-# ifdef HAVE_GTK2
- GError *gerr = 0;
-# endif /* HAVE_GTK2 */
-
- /* Find the size of the Drawable. */
- {
- Window root;
- int x, y;
- unsigned int bw;
- XGetGeometry (dpy, drawable,
- &root, &x, &y, &win_width, &win_height, &bw, &win_depth);
- }
-
- gdk_pixbuf_xlib_init_with_depth (dpy, screen_number (screen), win_depth);
-# ifdef HAVE_GTK2
-# if !GLIB_CHECK_VERSION(2, 36 ,0)
- g_type_init();
-# endif
-# else /* !HAVE_GTK2 */
- xlib_rgb_init (dpy, screen);
-# endif /* !HAVE_GTK2 */
-
- pb = gdk_pixbuf_new_from_file (filename
-# ifdef HAVE_GTK2
- , &gerr
-# endif /* HAVE_GTK2 */
- );
-
- if (!pb)
- {
- fprintf (stderr, "%s: unable to load \"%s\"\n", progname, filename);
-# ifdef HAVE_GTK2
- if (gerr && gerr->message && *gerr->message)
- fprintf (stderr, "%s: reason: %s\n", progname, gerr->message);
-# endif /* HAVE_GTK2 */
- return False;
- }
- else
- {
- int w = gdk_pixbuf_get_width (pb);
- int h = gdk_pixbuf_get_height (pb);
- int srcx, srcy, destx, desty, w2, h2;
- Bool bg_p = False;
-
-# ifdef HAVE_GDK_PIXBUF_APPLY_EMBEDDED_ORIENTATION
- {
- int ow = w, oh = h;
- GdkPixbuf *opb = pb;
- pb = gdk_pixbuf_apply_embedded_orientation (opb);
- g_object_unref (opb);
- w = gdk_pixbuf_get_width (pb);
- h = gdk_pixbuf_get_height (pb);
- if (verbose_p && (w != ow || h != oh))
- fprintf (stderr, "%s: rotated %dx%d to %dx%d\n",
- progname, ow, oh, w, h);
- }
-# endif
-
- compute_image_scaling (w, h, win_width, win_height, verbose_p,
- &srcx, &srcy, &destx, &desty, &w2, &h2);
- if (w != w2 || h != h2)
- {
- GdkPixbuf *pb2 = gdk_pixbuf_scale_simple (pb, w2, h2,
- GDK_INTERP_BILINEAR);
- if (pb2)
- {
- g_object_unref (pb);
- pb = pb2;
- w = w2;
- h = h2;
- }
- else
- fprintf (stderr, "%s: out of memory when scaling?\n", progname);
- }
-
- /* If we're rendering onto the root window (and it's not the
- xscreensaver pseudo-root) then put the image in the window's
- background. Otherwise, just paint the image onto the window.
- */
- bg_p = (window == drawable && root_window_p (screen, window));
-
- if (bg_p)
- {
- XGCValues gcv;
- GC gc;
- drawable = XCreatePixmap (dpy, window,
- win_width, win_height, win_depth);
- gcv.foreground = BlackPixelOfScreen (screen);
- gc = XCreateGC (dpy, drawable, GCForeground, &gcv);
- XFillRectangle (dpy, drawable, gc, 0, 0, win_width, win_height);
- XFreeGC (dpy, gc);
- }
- else
- clear_drawable (screen, drawable);
-
- /* #### Note that this always uses the default colormap! Morons!
- Owen says that in Gnome 2.0, I should try using
- gdk_pixbuf_render_pixmap_and_mask_for_colormap() instead.
- But I haven't tried.
- */
- if (srcx > 0) w -= srcx;
- if (srcy > 0) h -= srcy;
- gdk_pixbuf_xlib_render_to_drawable_alpha (pb, drawable,
- srcx, srcy, destx, desty,
- w, h,
- GDK_PIXBUF_ALPHA_FULL, 127,
- XLIB_RGB_DITHER_NORMAL,
- 0, 0);
- if (bg_p)
- {
- XSetWindowBackgroundPixmap (dpy, window, drawable);
- XClearWindow (dpy, window);
- }
-
- if (geom_ret)
- {
- geom_ret->x = destx;
- geom_ret->y = desty;
- geom_ret->width = w;
- geom_ret->height = h;
- }
- }
-
- XSync (dpy, False);
- return True;
-}
-
-#endif /* HAVE_GDK_PIXBUF */
-
-
-
-#ifdef HAVE_JPEGLIB
-
-/* Allocates a colormap that makes a PseudoColor or DirectColor
- visual behave like a TrueColor visual of the same depth.
-
- #### Duplicated in utils/grabscreen.c
- */
-static void
-allocate_cubic_colormap (Screen *screen, Visual *visual, Colormap cmap,
- Bool verbose_p)
-{
- Display *dpy = DisplayOfScreen (screen);
- int nr, ng, nb, cells;
- int r, g, b;
- int depth;
- XColor colors[4097];
- int i;
-
- depth = visual_depth (screen, visual);
-
- switch (depth)
- {
- case 8: nr = 3; ng = 3; nb = 2; cells = 256; break;
- case 12: nr = 4; ng = 4; nb = 4; cells = 4096; break;
- default: abort(); break;
- }
-
- memset(colors, 0, sizeof(colors));
- for (r = 0; r < (1 << nr); r++)
- for (g = 0; g < (1 << ng); g++)
- for (b = 0; b < (1 << nb); b++)
- {
- i = (r | (g << nr) | (b << (nr + ng)));
- colors[i].pixel = i;
- colors[i].flags = DoRed|DoGreen|DoBlue;
- if (depth == 8)
- {
- colors[i].red = ((r << 13) | (r << 10) | (r << 7) |
- (r << 4) | (r << 1));
- colors[i].green = ((g << 13) | (g << 10) | (g << 7) |
- (g << 4) | (g << 1));
- colors[i].blue = ((b << 14) | (b << 12) | (b << 10) |
- (b << 8) | (b << 6) | (b << 4) |
- (b << 2) | b);
- }
- else
- {
- colors[i].red = (r << 12) | (r << 8) | (r << 4) | r;
- colors[i].green = (g << 12) | (g << 8) | (g << 4) | g;
- colors[i].blue = (b << 12) | (b << 8) | (b << 4) | b;
- }
- }
-
- {
- int j;
- int allocated = 0;
- int interleave = cells / 8; /* skip around, rather than allocating in
- order, so that we get better coverage if
- we can't allocated all of them. */
- for (j = 0; j < interleave; j++)
- for (i = 0; i < cells; i += interleave)
- if (XAllocColor (dpy, cmap, &colors[i + j]))
- allocated++;
-
- if (verbose_p)
- fprintf (stderr, "%s: allocated %d of %d colors for cubic map\n",
- progname, allocated, cells);
- }
-}
-
-/* Find the pixel index that is closest to the given color
- (using linear distance in RGB space -- which is far from the best way.)
-
- #### Duplicated in utils/grabscreen.c
- */
-static unsigned long
-find_closest_pixel (XColor *colors, int ncolors,
- unsigned long r, unsigned long g, unsigned long b)
-{
- unsigned long distance = ~0;
- int i, found = 0;
-
- if (ncolors == 0)
- abort();
- for (i = 0; i < ncolors; i++)
- {
- unsigned long d;
- int rd, gd, bd;
-
- rd = r - colors[i].red;
- gd = g - colors[i].green;
- bd = b - colors[i].blue;
- if (rd < 0) rd = -rd;
- if (gd < 0) gd = -gd;
- if (bd < 0) bd = -bd;
- d = (rd << 1) + (gd << 2) + bd;
-
- if (d < distance)
- {
- distance = d;
- found = i;
- if (distance == 0)
- break;
- }
- }
-
- return found;
-}
-
-
-/* Given an XImage with 8-bit or 12-bit RGB data, convert it to be
- displayable with the given X colormap. The farther from a perfect
- color cube the contents of the colormap are, the lossier the
- transformation will be. No dithering is done.
-
- #### Duplicated in utils/grabscreen.c
- */
-static void
-remap_image (Screen *screen, Colormap cmap, XImage *image, Bool verbose_p)
-{
- Display *dpy = DisplayOfScreen (screen);
- unsigned long map[4097];
- int x, y, i;
- int cells;
- XColor colors[4097];
-
- if (image->depth == 8)
- cells = 256;
- else if (image->depth == 12)
- cells = 4096;
- else
- abort();
-
- memset(map, -1, sizeof(*map));
- memset(colors, -1, sizeof(*colors));
-
- for (i = 0; i < cells; i++)
- colors[i].pixel = i;
- XQueryColors (dpy, cmap, colors, cells);
-
- if (verbose_p)
- fprintf(stderr, "%s: building color cube for %d bit image\n",
- progname, image->depth);
-
- for (i = 0; i < cells; i++)
- {
- unsigned short r, g, b;
-
- if (cells == 256)
- {
- /* "RRR GGG BB" In an 8 bit map. Convert that to
- "RRR RRR RR" "GGG GGG GG" "BB BB BB BB" to give
- an even spread. */
- r = (i & 0x07);
- g = (i & 0x38) >> 3;
- b = (i & 0xC0) >> 6;
-
- r = ((r << 13) | (r << 10) | (r << 7) | (r << 4) | (r << 1));
- g = ((g << 13) | (g << 10) | (g << 7) | (g << 4) | (g << 1));
- b = ((b << 14) | (b << 12) | (b << 10) | (b << 8) |
- (b << 6) | (b << 4) | (b << 2) | b);
- }
- else
- {
- /* "RRRR GGGG BBBB" In a 12 bit map. Convert that to
- "RRRR RRRR" "GGGG GGGG" "BBBB BBBB" to give an even
- spread. */
- r = (i & 0x00F);
- g = (i & 0x0F0) >> 4;
- b = (i & 0xF00) >> 8;
-
- r = (r << 12) | (r << 8) | (r << 4) | r;
- g = (g << 12) | (g << 8) | (g << 4) | g;
- b = (b << 12) | (b << 8) | (b << 4) | b;
- }
-
- map[i] = find_closest_pixel (colors, cells, r, g, b);
- }
-
- if (verbose_p)
- fprintf(stderr, "%s: remapping colors in %d bit image\n",
- progname, image->depth);
-
- for (y = 0; y < image->height; y++)
- for (x = 0; x < image->width; x++)
- {
- unsigned long pixel = XGetPixel(image, x, y);
- if (pixel >= cells) abort();
- XPutPixel(image, x, y, map[pixel]);
- }
-}
-
-
-/* If the file has a PPM (P6) on it, read it and return an XImage.
- Otherwise, rewind the fd back to the beginning, and return 0.
- */
-static XImage *
-maybe_read_ppm (Screen *screen, Visual *visual,
- const char *filename, FILE *in, Bool verbose_p)
-{
- Display *dpy = DisplayOfScreen (screen);
- int depth = visual_depth (screen, visual);
- struct stat st;
- char *buf = 0;
- int bufsiz = 0;
- char *s, dummy;
- int i, j;
- int x, y, w, h, maxval;
- XImage *ximage = 0;
-
- if (fstat (fileno (in), &st))
- goto FAIL;
-
- bufsiz = st.st_size;
- buf = (char *) malloc (bufsiz + 1);
- if (!buf)
- {
- fprintf (stderr, "%s: out of memory loading %d byte PPM file %s\n",
- progname, bufsiz, filename);
- goto FAIL;
- }
-
- if (! (s = fgets (buf, bufsiz, in))) /* line 1 */
- goto FAIL;
-
- if (!strncmp (buf, "\107\111", 2))
- {
- fprintf (stderr, "%s: %s: sorry, GIF files not supported"
- " when compiled with JPEGlib instead of GDK_Pixbuf.\n",
- progname, filename);
- goto FAIL;
- }
- else if (!strncmp (buf, "\211\120", 2))
- {
- fprintf (stderr, "%s: %s: sorry, PNG files not supported"
- " when compiled with JPEGlib instead of GDK_Pixbuf.\n",
- progname, filename);
- goto FAIL;
- }
-
- if (strncmp (s, "P6", 2))
- goto FAIL;
-
- if (! (s = fgets (buf, bufsiz, in))) /* line 2 */
- goto FAIL;
- if (2 != sscanf (s, " %d %d %c", &w, &h, &dummy))
- {
- fprintf (stderr, "%s: %s: invalid PPM (line 2)\n", progname, filename);
- goto FAIL;
- }
-
- if (! (s = fgets (buf, bufsiz, in))) /* line 3 */
- goto FAIL;
- if (1 != sscanf (s, " %d %c", &maxval, &dummy))
- {
- fprintf (stderr, "%s: %s: invalid PPM (line 3)\n", progname, filename);
- goto FAIL;
- }
- if (maxval != 255)
- {
- fprintf (stderr, "%s: %s: unparsable PPM: maxval is %d\n",
- progname, filename, maxval);
- goto FAIL;
- }
-
- ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
- w, h, 8, 0);
- if (ximage)
- ximage->data = (char *) calloc (ximage->height, ximage->bytes_per_line);
- if (!ximage || !ximage->data)
- {
- fprintf (stderr, "%s: out of memory loading %dx%d PPM file %s\n",
- progname, ximage->width, ximage->height, filename);
- goto FAIL;
- }
-
- s = buf;
- j = bufsiz;
- while ((i = fread (s, 1, j, in)) > 0)
- s += i, j -= i;
-
- i = 0;
- for (y = 0; y < ximage->height; y++)
- for (x = 0; x < ximage->width; x++)
- {
- unsigned char r = buf[i++];
- unsigned char g = buf[i++];
- unsigned char b = buf[i++];
- unsigned long pixel;
-
- if (depth > 16)
- pixel = (r << 16) | (g << 8) | b;
- else if (depth == 8)
- pixel = ((r >> 5) | ((g >> 5) << 3) | ((b >> 6) << 6));
- else if (depth == 12)
- pixel = ((r >> 4) | ((g >> 4) << 4) | ((b >> 4) << 8));
- else if (depth == 16 || depth == 15)
- pixel = (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3)));
- else
- abort();
-
- XPutPixel (ximage, x, y, pixel);
- }
-
- free (buf);
- return ximage;
-
- FAIL:
- if (buf) free (buf);
- if (ximage && ximage->data)
- {
- free (ximage->data);
- ximage->data = 0;
- }
- if (ximage) XDestroyImage (ximage);
- fseek (in, 0, SEEK_SET);
- return 0;
-}
-
-
-typedef struct {
- struct jpeg_error_mgr pub; /* this is what passes for subclassing in C */
- const char *filename;
- Screen *screen;
- Visual *visual;
- Drawable drawable;
- Colormap cmap;
-} getimg_jpg_error_mgr;
-
-
-static void
-jpg_output_message (j_common_ptr cinfo)
-{
- getimg_jpg_error_mgr *err = (getimg_jpg_error_mgr *) cinfo->err;
- char buf[JMSG_LENGTH_MAX];
- cinfo->err->format_message (cinfo, buf);
- fprintf (stderr, "%s: %s: %s\n", progname, err->filename, buf);
-}
-
-
-static void
-jpg_error_exit (j_common_ptr cinfo)
-{
- getimg_jpg_error_mgr *err = (getimg_jpg_error_mgr *) cinfo->err;
- cinfo->err->output_message (cinfo);
- colorbars (err->screen, err->visual, err->drawable, err->cmap);
- XSync (DisplayOfScreen (err->screen), False);
- exit (1);
-}
-
-
-/* Reads a JPEG file, returns an RGB XImage of it.
- */
-static XImage *
-read_jpeg_ximage (Screen *screen, Visual *visual, Drawable drawable,
- Colormap cmap, const char *filename, Bool verbose_p)
-{
- Display *dpy = DisplayOfScreen (screen);
- int depth = visual_depth (screen, visual);
-
- FILE *in = 0;
- XImage *ximage = 0;
- struct jpeg_decompress_struct cinfo;
- getimg_jpg_error_mgr jerr;
- JSAMPARRAY scanbuf = 0;
- int y;
-
- jerr.filename = filename;
- jerr.screen = screen;
- jerr.visual = visual;
- jerr.drawable = drawable;
- jerr.cmap = cmap;
-
- if (! (depth >= 15 || depth == 12 || depth == 8))
- {
- fprintf (stderr, "%s: unsupported depth: %d\n", progname, depth);
- goto FAIL;
- }
-
- in = fopen (filename, "rb");
- if (!in)
- {
- fprintf (stderr, "%s: %s: unreadable\n", progname, filename);
- goto FAIL;
- }
-
- /* Check to see if it's a PPM, and if so, read that instead of using
- the JPEG library. Yeah, this is all modular and stuff.
- */
- if ((ximage = maybe_read_ppm (screen, visual, filename, in, verbose_p)))
- {
- fclose (in);
- return ximage;
- }
-
- cinfo.err = jpeg_std_error (&jerr.pub);
- jerr.pub.output_message = jpg_output_message;
- jerr.pub.error_exit = jpg_error_exit;
-
- jpeg_create_decompress (&cinfo);
- jpeg_stdio_src (&cinfo, in);
- jpeg_read_header (&cinfo, TRUE);
-
- /* set some decode parameters */
- cinfo.out_color_space = JCS_RGB;
- cinfo.quantize_colors = FALSE;
-
- jpeg_start_decompress (&cinfo);
-
- ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
- cinfo.output_width, cinfo.output_height,
- 8, 0);
- if (ximage)
- ximage->data = (char *) calloc (ximage->height, ximage->bytes_per_line);
-
- if (ximage && ximage->data)
- scanbuf = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE,
- cinfo.rec_outbuf_height *
- cinfo.output_width *
- cinfo.output_components,
- 1);
- if (!ximage || !ximage->data || !scanbuf)
- {
- fprintf (stderr, "%s: out of memory loading %dx%d file %s\n",
- progname, ximage->width, ximage->height, filename);
- goto FAIL;
- }
-
- y = 0;
- while (cinfo.output_scanline < cinfo.output_height)
- {
- int n = jpeg_read_scanlines (&cinfo, scanbuf, 1);
- int i;
- for (i = 0; i < n; i++)
- {
- int x;
- for (x = 0; x < ximage->width; x++)
- {
- int j = x * cinfo.output_components;
- unsigned char r = scanbuf[i][j];
- unsigned char g = scanbuf[i][j+1];
- unsigned char b = scanbuf[i][j+2];
- unsigned long pixel;
-
- if (depth > 16)
- pixel = (r << 16) | (g << 8) | b;
- else if (depth == 8)
- pixel = ((r >> 5) | ((g >> 5) << 3) | ((b >> 6) << 6));
- else if (depth == 12)
- pixel = ((r >> 4) | ((g >> 4) << 4) | ((b >> 4) << 8));
- else if (depth == 15)
- /* Gah! I don't understand why these are in the other
- order. */
- pixel = (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3)));
- else if (depth == 16)
- pixel = (((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3)));
- else
- abort();
-
- XPutPixel (ximage, x, y, pixel);
- }
- y++;
- }
- }
-
- if (cinfo.output_scanline < cinfo.output_height)
- /* don't goto FAIL -- we might have viewable partial data. */
- jpeg_abort_decompress (&cinfo);
- else
- jpeg_finish_decompress (&cinfo);
-
- jpeg_destroy_decompress (&cinfo);
- fclose (in);
- in = 0;
-
- return ximage;
-
- FAIL:
- if (in) fclose (in);
- if (ximage && ximage->data)
- {
- free (ximage->data);
- ximage->data = 0;
- }
- if (ximage) XDestroyImage (ximage);
- if (scanbuf) free (scanbuf);
- return 0;
-}
-
-
-/* Reads the given image file and renders it on the Drawable, using JPEG lib.
- Returns False if it fails.
- */
-static Bool
-read_file_jpeglib (Screen *screen, Window window, Drawable drawable,
- const char *filename, Bool verbose_p,
- XRectangle *geom_ret)
-{
- Display *dpy = DisplayOfScreen (screen);
- XImage *ximage;
- Visual *visual;
- int class, depth;
- Colormap cmap;
- unsigned int win_width, win_height, win_depth;
- int srcx, srcy, destx, desty, w2, h2;
-
- /* Find the size of the Drawable, and the Visual/Colormap of the Window. */
- {
- Window root;
- int x, y;
- unsigned int bw;
- XWindowAttributes xgwa;
- XGetWindowAttributes (dpy, window, &xgwa);
- visual = xgwa.visual;
- cmap = xgwa.colormap;
- XGetGeometry (dpy, drawable,
- &root, &x, &y, &win_width, &win_height, &bw, &win_depth);
- }
-
- /* Make sure we're not on some weirdo visual...
- */
- class = visual_class (screen, visual);
- depth = visual_depth (screen, visual);
- if ((class == PseudoColor || class == DirectColor) &&
- (depth != 8 && depth != 12))
- {
- fprintf (stderr, "%s: Pseudo/DirectColor depth %d unsupported\n",
- progname, depth);
- return False;
- }
-
- /* Read the file...
- */
- ximage = read_jpeg_ximage (screen, visual, drawable, cmap,
- filename, verbose_p);
- if (!ximage) return False;
-
- /* Scale it, if necessary...
- */
- compute_image_scaling (ximage->width, ximage->height,
- win_width, win_height, verbose_p,
- &srcx, &srcy, &destx, &desty, &w2, &h2);
- if (ximage->width != w2 || ximage->height != h2)
- if (! scale_ximage (screen, visual, ximage, w2, h2))
- return False;
-
- /* Allocate a colormap, if we need to...
- */
- if (class == PseudoColor || class == DirectColor)
- {
- allocate_cubic_colormap (screen, visual, cmap, verbose_p);
- remap_image (screen, cmap, ximage, verbose_p);
- }
-
- /* Finally, put the resized image on the window.
- */
- {
- GC gc;
- XGCValues gcv;
-
- /* If we're rendering onto the root window (and it's not the xscreensaver
- pseudo-root) then put the image in the window's background. Otherwise,
- just paint the image onto the window.
- */
- if (window == drawable && root_window_p (screen, window))
- {
- Pixmap bg = XCreatePixmap (dpy, window,
- win_width, win_height, win_depth);
- gcv.foreground = BlackPixelOfScreen (screen);
- gc = XCreateGC (dpy, drawable, GCForeground, &gcv);
- XFillRectangle (dpy, bg, gc, 0, 0, win_width, win_height);
- XPutImage (dpy, bg, gc, ximage,
- srcx, srcy, destx, desty, ximage->width, ximage->height);
- XSetWindowBackgroundPixmap (dpy, window, bg);
- XClearWindow (dpy, window);
- }
- else
- {
- gc = XCreateGC (dpy, drawable, 0, &gcv);
- clear_drawable (screen, drawable);
- XPutImage (dpy, drawable, gc, ximage,
- srcx, srcy, destx, desty, ximage->width, ximage->height);
- }
-
- XFreeGC (dpy, gc);
- }
-
- if (geom_ret)
- {
- geom_ret->x = destx;
- geom_ret->y = desty;
- geom_ret->width = ximage->width;
- geom_ret->height = ximage->height;
- }
-
- free (ximage->data);
- ximage->data = 0;
- XDestroyImage (ximage);
- XSync (dpy, False);
- return True;
-}
-
-#endif /* HAVE_JPEGLIB */
-
-
-/* Reads the given image file and renders it on the Drawable.
- Returns False if it fails.
- */
-static Bool
-display_file (Screen *screen, Window window, Drawable drawable,
- const char *filename, Bool verbose_p,
- XRectangle *geom_ret)
-{
- if (verbose_p)
- fprintf (stderr, "%s: loading \"%s\"\n", progname, filename);
-
-# if defined(HAVE_GDK_PIXBUF)
- if (read_file_gdk (screen, window, drawable, filename, verbose_p, geom_ret))
- return True;
-# elif defined(HAVE_JPEGLIB)
- if (read_file_jpeglib (screen, window, drawable, filename, verbose_p,
- geom_ret))
- return True;
-# else /* !(HAVE_GDK_PIXBUF || HAVE_JPEGLIB) */
- /* shouldn't get here if we have no image-loading methods available. */
- abort();
-# endif /* !(HAVE_GDK_PIXBUF || HAVE_JPEGLIB) */
-
- return False;
-}
-
-
-/* Invokes a sub-process and returns its output (presumably, a file to
- load.) Free the string when done. 'grab_type' controls which program
- to run. Returned pathname may be relative to 'directory', or absolute.
- */
-static char *
-get_filename_1 (Screen *screen, const char *directory, grab_type type,
- Bool verbose_p)
-{
- Display *dpy = DisplayOfScreen (screen);
- pid_t forked;
- int fds [2];
- int in, out;
- char buf[10240];
- char *av[20];
- int ac = 0;
-
- switch (type)
- {
- case GRAB_FILE:
- av[ac++] = GETIMAGE_FILE_PROGRAM;
- if (verbose_p)
- av[ac++] = "--verbose";
- av[ac++] = "--name";
- av[ac++] = (char *) directory;
- break;
-
- case GRAB_VIDEO:
- av[ac++] = GETIMAGE_VIDEO_PROGRAM;
- if (verbose_p)
- av[ac++] = "--verbose";
- av[ac++] = "--name";
- break;
-
-# ifdef USE_EXTERNAL_SCREEN_GRABBER
- case GRAB_DESK:
- av[ac++] = GETIMAGE_SCREEN_PROGRAM;
- if (verbose_p)
- av[ac++] = "--verbose";
- av[ac++] = "--name";
- break;
-# endif
-
- default:
- abort();
- }
- av[ac] = 0;
-
- if (verbose_p)
- {
- int i;
- fprintf (stderr, "%s: executing:", progname);
- for (i = 0; i < ac; i++)
- fprintf (stderr, " %s", av[i]);
- fprintf (stderr, "\n");
- }
-
- if (pipe (fds))
- {
- sprintf (buf, "%s: error creating pipe", progname);
- perror (buf);
- return 0;
- }
-
- in = fds [0];
- out = fds [1];
-
- switch ((int) (forked = fork ()))
- {
- case -1:
- {
- sprintf (buf, "%s: couldn't fork", progname);
- perror (buf);
- return 0;
- }
- 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 */
- {
- sprintf (buf, "%s: could not dup() a new stdout", progname);
- exit (-1); /* exits fork */
- }
-
- execvp (av[0], av); /* shouldn't return. */
- exit (-1); /* exits fork */
- break;
- }
- default:
- {
- struct stat st;
- int wait_status = 0;
- FILE *f = fdopen (in, "r");
- int L;
- char *ret = 0;
-
- 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);
-
- L = strlen (buf);
- while (L && buf[L-1] == '\n')
- buf[--L] = 0;
-
- if (!*buf)
- return 0;
-
- ret = strdup (buf);
-
- if (*ret != '/')
- {
- /* Program returned path relative to directory. Prepend dir
- to buf so that we can properly stat it. */
- strcpy (buf, directory);
- if (directory[strlen(directory)-1] != '/')
- strcat (buf, "/");
- strcat (buf, ret);
- }
-
- if (stat(buf, &st))
- {
- fprintf (stderr, "%s: file does not exist: \"%s\"\n",
- progname, buf);
- free (ret);
- return 0;
- }
- else
- return ret;
- }
- }
-
- abort();
-}
-
-
-/* Returns a pathname to an image file. Free the string when you're done.
- */
-static char *
-get_filename (Screen *screen, const char *directory, Bool verbose_p)
-{
- return get_filename_1 (screen, directory, GRAB_FILE, verbose_p);
-}
-
-
-/* Grabs a video frame to a file, and returns a pathname to that file.
- Delete that file when you are done with it (and free the string.)
- */
-static char *
-get_video_filename (Screen *screen, Bool verbose_p)
-{
- return get_filename_1 (screen, 0, GRAB_VIDEO, verbose_p);
-}
-
-/* Grabs a desktop image to a file, and returns a pathname to that file.
- Delete that file when you are done with it (and free the string.)
- */
-# ifdef USE_EXTERNAL_SCREEN_GRABBER
-static char *
-get_desktop_filename (Screen *screen, Bool verbose_p)
-{
- return get_filename_1 (screen, 0, GRAB_DESK, verbose_p);
-}
-#endif /* USE_EXTERNAL_SCREEN_GRABBER */
-
-
-/* Grabs a video frame, and renders it on the Drawable.
- Returns False if it fails;
- */
-static Bool
-display_video (Screen *screen, Window window, Drawable drawable,
- Bool verbose_p, XRectangle *geom_ret)
-{
- char *filename = get_video_filename (screen, verbose_p);
- Bool status;
-
- if (!filename)
- {
- if (verbose_p)
- fprintf (stderr, "%s: video grab failed.\n", progname);
- return False;
- }
-
- status = display_file (screen, window, drawable, filename, verbose_p,
- geom_ret);
-
- if (unlink (filename))
- {
- char buf[512];
- sprintf (buf, "%s: rm %.100s", progname, filename);
- perror (buf);
- }
- else if (verbose_p)
- fprintf (stderr, "%s: rm %s\n", progname, filename);
-
- if (filename) free (filename);
- return status;
-}
-
-
-/* Grabs a desktop screen shot onto the window and the drawable.
- If the window and drawable are not the same size, the image in
- the drawable is scaled to fit.
- Returns False if it fails.
- */
-static Bool
-display_desktop (Screen *screen, Window window, Drawable drawable,
- Bool verbose_p, XRectangle *geom_ret)
-{
-# ifdef USE_EXTERNAL_SCREEN_GRABBER
-
- Display *dpy = DisplayOfScreen (screen);
- Bool top_p = top_level_window_p (screen, window);
- char *filename;
- Bool status;
-
- if (top_p)
- {
- if (verbose_p)
- fprintf (stderr, "%s: unmapping 0x%lx.\n", progname,
- (unsigned long) window);
- XUnmapWindow (dpy, window);
- XSync (dpy, False);
- }
-
- filename = get_desktop_filename (screen, verbose_p);
-
- if (top_p)
- {
- if (verbose_p)
- fprintf (stderr, "%s: mapping 0x%lx.\n", progname,
- (unsigned long) window);
- XMapRaised (dpy, window);
- XSync (dpy, False);
- }
-
- if (!filename)
- {
- if (verbose_p)
- fprintf (stderr, "%s: desktop grab failed.\n", progname);
- return False;
- }
-
- status = display_file (screen, window, drawable, filename, verbose_p,
- geom_ret);
-
- if (unlink (filename))
- {
- char buf[512];
- sprintf (buf, "%s: rm %.100s", progname, filename);
- perror (buf);
- }
- else if (verbose_p)
- fprintf (stderr, "%s: rm %s\n", progname, filename);
-
- if (filename) free (filename);
- return status;
-
-# else /* !USE_EXTERNAL_SCREEN_GRABBER */
-
- Display *dpy = DisplayOfScreen (screen);
- XGCValues gcv;
- XWindowAttributes xgwa;
- Window root;
- int px, py;
- unsigned int pw, ph, pbw, pd;
- int srcx, srcy, destx, desty, w2, h2;
-
- if (verbose_p)
- {
- fprintf (stderr, "%s: grabbing desktop image\n", progname);
- grabscreen_verbose();
- }
-
- XGetWindowAttributes (dpy, window, &xgwa);
- XGetGeometry (dpy, drawable, &root, &px, &py, &pw, &ph, &pbw, &pd);
-
- grab_screen_image_internal (screen, window);
-
- compute_image_scaling (xgwa.width, xgwa.height,
- pw, ph, verbose_p,
- &srcx, &srcy, &destx, &desty, &w2, &h2);
-
- if (pw == w2 && ph == h2) /* it fits -- just copy server-side pixmaps */
- {
- GC gc = XCreateGC (dpy, drawable, 0, &gcv);
- XCopyArea (dpy, window, drawable, gc,
- 0, 0, xgwa.width, xgwa.height, 0, 0);
- XFreeGC (dpy, gc);
- }
- else /* size mismatch -- must scale client-side images to fit drawable */
- {
- GC gc;
- XImage *ximage = 0;
- XErrorHandler old_handler;
-
- XSync (dpy, False);
- old_handler = XSetErrorHandler (ignore_badmatch_ehandler);
- error_handler_hit_p = False;
-
- /* This can return BadMatch if the window is not fully on screen.
- Trap that error and return color bars in that case.
- (Note that this only happens with XGetImage, not with XCopyArea:
- yet another totally gratuitous inconsistency in X, thanks.)
- */
- ximage = XGetImage (dpy, window, 0, 0, xgwa.width, xgwa.height,
- ~0L, ZPixmap);
-
- XSync (dpy, False);
- XSetErrorHandler (old_handler);
- XSync (dpy, False);
-
- if (error_handler_hit_p)
- {
- ximage = 0;
- if (verbose_p)
- fprintf (stderr, "%s: BadMatch reading window 0x%x contents!\n",
- progname, (unsigned int) window);
- }
-
- if (!ximage ||
- !scale_ximage (xgwa.screen, xgwa.visual, ximage, w2, h2))
- return False;
-
- gc = XCreateGC (dpy, drawable, 0, &gcv);
- clear_drawable (screen, drawable);
- XPutImage (dpy, drawable, gc, ximage,
- srcx, srcy, destx, desty, ximage->width, ximage->height);
- XDestroyImage (ximage);
- XFreeGC (dpy, gc);
- }
-
- if (geom_ret)
- {
- geom_ret->x = destx;
- geom_ret->y = desty;
- geom_ret->width = w2;
- geom_ret->height = h2;
- }
-
- XSync (dpy, False);
- return True;
-
-# endif /* !USE_EXTERNAL_SCREEN_GRABBER */
-}
-
-
-/* Whether the given Drawable is unreasonably small.
- */
-static Bool
-drawable_miniscule_p (Display *dpy, Drawable drawable)
-{
- Window root;
- int xx, yy;
- unsigned int bw, d, w = 0, h = 0;
- XGetGeometry (dpy, drawable, &root, &xx, &yy, &w, &h, &bw, &d);
- return (w < 32 || h < 30);
-}
-
-
-/* Grabs an image (from a file, video, or the desktop) and renders it on
- the Drawable. If `file' is specified, always use that file. Otherwise,
- select randomly, based on the other arguments.
- */
-static void
-get_image (Screen *screen,
- Window window, Drawable drawable,
- Bool verbose_p,
- Bool desk_p,
- Bool video_p,
- Bool image_p,
- const char *dir,
- const char *file)
-{
- Display *dpy = DisplayOfScreen (screen);
- grab_type which = GRAB_BARS;
- struct stat st;
- const char *file_prop = 0;
- char *absfile = 0;
- XRectangle geom = { 0, 0, 0, 0 };
-
- if (! drawable_window_p (dpy, window))
- {
- fprintf (stderr, "%s: 0x%lx is a pixmap, not a window!\n",
- progname, (unsigned long) window);
- exit (1);
- }
-
- /* Make sure the Screen and the Window correspond. */
- {
- XWindowAttributes xgwa;
- XGetWindowAttributes (dpy, window, &xgwa);
- screen = xgwa.screen;
- }
-
- if (file && stat (file, &st))
- {
- fprintf (stderr, "%s: file \"%s\" does not exist\n", progname, file);
- file = 0;
- }
-
- if (verbose_p)
- {
- fprintf (stderr, "%s: grabDesktopImages: %s\n",
- progname, desk_p ? "True" : "False");
- fprintf (stderr, "%s: grabVideoFrames: %s\n",
- progname, video_p ? "True" : "False");
- fprintf (stderr, "%s: chooseRandomImages: %s\n",
- progname, image_p ? "True" : "False");
- fprintf (stderr, "%s: imageDirectory: %s\n",
- progname, (file ? file : dir ? dir : ""));
- }
-
-# if !(defined(HAVE_GDK_PIXBUF) || defined(HAVE_JPEGLIB))
- image_p = False; /* can't load images from files... */
-# ifdef USE_EXTERNAL_SCREEN_GRABBER
- desk_p = False; /* ...or from desktops grabbed to files. */
-# endif
-
- if (file)
- {
- fprintf (stderr,
- "%s: image file loading not available at compile-time\n",
- progname);
- fprintf (stderr, "%s: can't load \"%s\"\n", progname, file);
- file = 0;
- }
-# endif /* !(HAVE_GDK_PIXBUF || HAVE_JPEGLIB) */
-
- if (file)
- {
- desk_p = False;
- video_p = False;
- image_p = True;
- }
- else if (!dir || !*dir)
- {
- if (verbose_p && image_p)
- fprintf (stderr,
- "%s: no imageDirectory: turning off chooseRandomImages.\n",
- progname);
- image_p = False;
- }
-
- /* If the target drawable is really small, no good can come of that.
- Always do colorbars in that case.
- */
- if (drawable_miniscule_p (dpy, drawable))
- {
- desk_p = False;
- video_p = False;
- image_p = False;
- }
-
-# ifndef _VROOT_H_
-# error Error! This file definitely needs vroot.h!
-# endif
-
- /* We can grab desktop images (using the normal X11 method) if:
- - the window is the real root window;
- - the window is a toplevel window.
- We cannot grab desktop images that way if:
- - the window is a non-top-level window.
-
- Under X11 on MacOS, desktops are just like loaded image files.
- Under Cocoa on MacOS, this code is not used at all.
- */
-# ifndef USE_EXTERNAL_SCREEN_GRABBER
- if (desk_p)
- {
- if (!top_level_window_p (screen, window))
- {
- desk_p = False;
- if (verbose_p)
- fprintf (stderr,
- "%s: 0x%x not top-level: turning off grabDesktopImages.\n",
- progname, (unsigned int) window);
- }
- }
-# endif /* !USE_EXTERNAL_SCREEN_GRABBER */
-
- if (! (desk_p || video_p || image_p))
- which = GRAB_BARS;
- else
- {
- int i = 0;
- int n;
- /* Loop until we get one that's permitted.
- If files or video are permitted, do them more often
- than desktop.
-
- D+V+I: 10% + 45% + 45%.
- V+I: 50% + 50%
- D+V: 18% + 82%
- D+I: 18% + 82%
- */
- AGAIN:
- n = (random() % 100);
- if (++i > 300) abort();
- else if (desk_p && n < 10) which = GRAB_DESK; /* 10% */
- else if (video_p && n < 55) which = GRAB_VIDEO; /* 45% */
- else if (image_p) which = GRAB_FILE; /* 45% */
- else goto AGAIN;
- }
-
-
- /* If we're to search a directory to find an image file, do so now.
- */
- if (which == GRAB_FILE && !file)
- {
- file = get_filename (screen, dir, verbose_p);
- if (!file)
- {
- which = GRAB_BARS;
- if (verbose_p)
- fprintf (stderr, "%s: no image files found.\n", progname);
- }
- }
-
- /* Now actually render something.
- */
- switch (which)
- {
- case GRAB_BARS:
- {
- XWindowAttributes xgwa;
- COLORBARS:
- if (verbose_p)
- fprintf (stderr, "%s: drawing colorbars.\n", progname);
- XGetWindowAttributes (dpy, window, &xgwa);
- colorbars (screen, xgwa.visual, drawable, xgwa.colormap);
- XSync (dpy, False);
- if (! file_prop) file_prop = "";
-
- }
- break;
-
- case GRAB_DESK:
- if (! display_desktop (screen, window, drawable, verbose_p, &geom))
- goto COLORBARS;
- file_prop = "desktop";
- break;
-
- case GRAB_FILE:
- if (*file && *file != '/') /* pathname is relative to dir. */
- {
- if (absfile) free (absfile);
- absfile = malloc (strlen(dir) + strlen(file) + 10);
- strcpy (absfile, dir);
- if (dir[strlen(dir)-1] != '/')
- strcat (absfile, "/");
- strcat (absfile, file);
- }
- if (! display_file (screen, window, drawable,
- (absfile ? absfile : file),
- verbose_p, &geom))
- goto COLORBARS;
- file_prop = file;
- break;
-
- case GRAB_VIDEO:
- if (! display_video (screen, window, drawable, verbose_p, &geom))
- goto COLORBARS;
- file_prop = "video";
- break;
-
- default:
- abort();
- break;
- }
-
- {
- Atom a = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_FILENAME, False);
- if (file_prop && *file_prop)
- {
- char *f2 = strdup (file_prop);
-
- /* Take the extension off of the file name. */
- /* Duplicated in utils/grabclient.c. */
- char *slash = strrchr (f2, '/');
- char *dot = strrchr ((slash ? slash : f2), '.');
- if (dot) *dot = 0;
- /* Replace slashes with newlines */
- /* while ((dot = strchr(f2, '/'))) *dot = '\n'; */
- /* Replace slashes with spaces */
- /* while ((dot = strchr(f2, '/'))) *dot = ' '; */
-
- XChangeProperty (dpy, window, a, XA_STRING, 8, PropModeReplace,
- (unsigned char *) f2, strlen(f2));
- free (f2);
- }
- else
- XDeleteProperty (dpy, window, a);
-
- a = XInternAtom (dpy, XA_XSCREENSAVER_IMAGE_GEOMETRY, False);
- if (geom.width > 0)
- {
- char gstr[30];
- sprintf (gstr, "%dx%d+%d+%d", geom.width, geom.height, geom.x, geom.y);
- XChangeProperty (dpy, window, a, XA_STRING, 8, PropModeReplace,
- (unsigned char *) gstr, strlen (gstr));
- }
- else
- XDeleteProperty (dpy, window, a);
- }
-
- if (absfile) free (absfile);
- XSync (dpy, False);
-}
-
-
-#ifdef DEBUG
-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 /* DEBUG */
-
-
-#define USAGE "usage: %s [ -options... ] window-id [pixmap-id]\n" \
- "\n" \
- " %s\n" \
- "\n" \
- " %s puts an image on the given window or pixmap.\n" \
- "\n" \
- " It is used by those xscreensaver demos that operate on images.\n" \
- " The image may be a file loaded from disk, a frame grabbed from\n" \
- " the system's video camera, or a screenshot of the desktop,\n" \
- " depending on command-line options or the ~/.xscreensaver file.\n" \
- "\n" \
- " Options include:\n" \
- "\n" \
- " -display host:dpy.screen which display to use\n" \
- " -root draw to the root window\n" \
- " -verbose print diagnostics\n" \
- " -images / -no-images whether to allow image file loading\n" \
- " -video / -no-video whether to allow video grabs\n" \
- " -desktop / -no-desktop whether to allow desktop screen grabs\n"\
- " -directory <path> where to find image files to load\n" \
- " -file <filename> load this image file\n" \
- "\n" \
- " The XScreenSaver Control Panel (xscreensaver-demo) lets you set the\n"\
- " defaults for these options in your ~/.xscreensaver file.\n" \
- "\n"
-
-int
-main (int argc, char **argv)
-{
- saver_preferences P;
- Widget toplevel;
- Display *dpy;
- Screen *screen;
- char *oprogname = progname;
- char *file = 0;
- char version[255];
-
- Window window = (Window) 0;
- Drawable drawable = (Drawable) 0;
- const char *window_str = 0;
- const char *drawable_str = 0;
- char *s;
- int i;
-
- progname = argv[0];
- s = strrchr (progname, '/');
- if (s) progname = s+1;
- oprogname = progname;
-
- /* half-assed way of avoiding buffer-overrun attacks. */
- if (strlen (progname) >= 100) progname[100] = 0;
-
-# ifndef _VROOT_H_
-# error Error! This file definitely needs vroot.h!
-# endif
-
- /* Get the version number, for error messages. */
- {
- 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 (version, "Part of XScreenSaver %s -- %s.", s1, s3);
- free(v);
- }
-
- /* 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.
- */
- progname = argv[0] = "xscreensaver";
-
- /* allow one dash or two. */
- for (i = 1; i < argc; i++)
- if (argv[i][0] == '-' && argv[i][1] == '-') argv[i]++;
-
- toplevel = XtAppInitialize (&app, progclass, 0, 0, &argc, argv,
- defaults, 0, 0);
- dpy = XtDisplay (toplevel);
- screen = XtScreen (toplevel);
- db = XtDatabase (dpy);
- XtGetApplicationNameAndClass (dpy, &s, &progclass);
- XSetErrorHandler (x_ehandler);
- XSync (dpy, False);
-
- /* Randomize -- only need to do this here because this program
- doesn't use the `screenhack.h' or `lockmore.h' APIs. */
-# undef ya_rand_init
- ya_rand_init (0);
-
- memset (&P, 0, sizeof(P));
- P.db = db;
- load_init_file (dpy, &P);
-
- progname = argv[0] = oprogname;
-
- for (i = 1; i < argc; i++)
- {
- unsigned long w;
- char dummy;
-
- /* Have to re-process these, or else the .xscreensaver file
- has priority over the command line...
- */
- if (!strcmp (argv[i], "-v") || !strcmp (argv[i], "-verbose"))
- P.verbose_p = True;
- else if (!strcmp (argv[i], "-desktop")) P.grab_desktop_p = True;
- else if (!strcmp (argv[i], "-no-desktop")) P.grab_desktop_p = False;
- else if (!strcmp (argv[i], "-video")) P.grab_video_p = True;
- else if (!strcmp (argv[i], "-no-video")) P.grab_video_p = False;
- else if (!strcmp (argv[i], "-images")) P.random_image_p = True;
- else if (!strcmp (argv[i], "-no-images")) P.random_image_p = False;
- else if (!strcmp (argv[i], "-file")) file = argv[++i];
- else if (!strcmp (argv[i], "-directory") || !strcmp (argv[i], "-dir"))
- P.image_directory = argv[++i];
- else if (!strcmp (argv[i], "-root") || !strcmp (argv[i], "root"))
- {
- if (window)
- {
- fprintf (stderr, "%s: both %s and %s specified?\n",
- progname, argv[i], window_str);
- goto LOSE;
- }
- window_str = argv[i];
- window = VirtualRootWindowOfScreen (screen);
- }
- else if ((1 == sscanf (argv[i], " 0x%lx %c", &w, &dummy) ||
- 1 == sscanf (argv[i], " %lu %c", &w, &dummy)) &&
- w != 0)
- {
- if (drawable)
- {
- fprintf (stderr, "%s: both %s and %s specified?\n",
- progname, drawable_str, argv[i]);
- goto LOSE;
- }
- else if (window)
- {
- drawable_str = argv[i];
- drawable = (Drawable) w;
- }
- else
- {
- window_str = argv[i];
- window = (Window) w;
- }
- }
- else
- {
- if (argv[i][0] == '-')
- fprintf (stderr, "\n%s: unknown option \"%s\"\n",
- progname, argv[i]);
- else
- fprintf (stderr, "\n%s: unparsable window/pixmap ID: \"%s\"\n",
- progname, argv[i]);
- LOSE:
-# 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
- fprintf (stderr, USAGE, progname, version, progname);
- exit (1);
- }
- }
-
- if (window == 0)
- {
- fprintf (stderr, "\n%s: no window ID specified!\n", progname);
- goto LOSE;
- }
-
-
-#ifdef DEBUG
- if (P.verbose_p) /* Print out all the resources we can see. */
- {
- XrmName name = { 0 };
- XrmClass class = { 0 };
- int count = 0;
- XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper,
- (XtPointer) &count);
- }
-#endif /* DEBUG */
-
- if (!window) abort();
- if (!drawable) drawable = window;
-
- get_image (screen, window, drawable, P.verbose_p,
- P.grab_desktop_p, P.grab_video_p, P.random_image_p,
- P.image_directory, file);
- exit (0);
-}
diff --git a/driver/xset.c b/driver/xset.c
deleted file mode 100644
index a381429..0000000
--- a/driver/xset.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/* xset.c --- interacting with server extensions and the builtin screensaver.
- * xscreensaver, Copyright (c) 1991-2008 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. 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 <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Xos.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"
-
-#ifdef _VROOT_H_
-ERROR! You must not include vroot.h in this file.
-#endif
-
-
-/* MIT SCREEN-SAVER server extension hackery.
- */
-
-#ifdef HAVE_MIT_SAVER_EXTENSION
-
-# include <X11/extensions/scrnsaver.h>
-
-static int
-ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
-{
- return 0;
-}
-
-static void
-init_mit_saver_extension (saver_info *si)
-{
- int i;
- Pixmap *blank_pix = (Pixmap *) calloc (sizeof(Pixmap), si->nscreens);
-
- for (i = 0; i < si->nscreens; i++)
- {
- saver_screen_info *ssi = &si->screens[i];
- XID kill_id = 0;
- Atom kill_type = 0;
- Window root = RootWindowOfScreen (ssi->screen);
- blank_pix[i] = XCreatePixmap (si->dpy, root, 1, 1, 1);
-
- /* Kill off the old MIT-SCREEN-SAVER client if there is one.
- This tends to generate X errors, though (possibly due to a bug
- in the server extension itself?) so just ignore errors here. */
- if (XScreenSaverGetRegistered (si->dpy,
- XScreenNumberOfScreen (ssi->screen),
- &kill_id, &kill_type)
- && kill_id != blank_pix[i])
- {
- XErrorHandler old_handler =
- XSetErrorHandler (ignore_all_errors_ehandler);
- XKillClient (si->dpy, kill_id);
- XSync (si->dpy, False);
- XSetErrorHandler (old_handler);
- }
- XScreenSaverSelectInput (si->dpy, root, ScreenSaverNotifyMask);
- XScreenSaverRegister (si->dpy,
- XScreenNumberOfScreen (ssi->screen),
- (XID) blank_pix[i], XA_PIXMAP);
- }
- free(blank_pix);
-}
-#endif /* HAVE_MIT_SAVER_EXTENSION */
-
-
-#ifdef HAVE_XINPUT
-/* XInputExtension device support */
-
-Bool
-query_xinput_extension (saver_info *si)
-{
- XExtCodes codes;
- return XQueryExtension (si->dpy, INAME, &codes.major_opcode,
- &codes.first_event, &codes.first_error);
-}
-
-void
-init_xinput_extension (saver_info *si)
-{
- int i, ndevices;
- int class;
- XDeviceInfo *list;
- XDevice *dev;
- XAnyClassPtr pClass;
- XEventClass *event_list;
- int nevents = 0;
-
- /* skip if already initialized */
- if (si->num_xinput_devices && si->xinput_devices)
- return;
-
- si->num_xinput_devices = 0;
-
- list = XListInputDevices (si->dpy, &ndevices);
- if (list == NULL)
- {
- si->xinput_devices = NULL;
- return;
- }
-
- /* We only care about 3 event types per device (DeviceButtonPress,
- DeviceButtonRelease, and DeviceMotionNotify), hence the "* 3"
- for the event count. */
- event_list = calloc(ndevices * 3, sizeof(XEventClass));
- if (event_list == NULL)
- return;
-
- si->xinput_devices = calloc(ndevices, sizeof(struct xinput_dev_info));
- if (si->xinput_devices == NULL)
- {
- free(event_list);
- return;
- }
-
- for (i = 0; i < ndevices; i++)
- {
- if ((list[i].use == IsXExtensionDevice)
-#ifdef IsXExtensionPointer
- || (list[i].use == IsXExtensionPointer)
-#endif
- )
- {
- struct xinput_dev_info *dev_info =
- &si->xinput_devices[si->num_xinput_devices];
- Bool device_we_want = False;
-
- if (si->prefs.debug_p)
- fprintf(stderr,
- "Extension device #%2d: XID=%2d type=%3d name=\"%s\"\n",
- i, (int) list[i].id, (int) list[i].type, list[i].name);
-
- dev = XOpenDevice (si->dpy, list[i].id);
- if (!dev)
- continue;
- dev_info->device = dev;
-
- pClass = list[i].inputclassinfo;
- for (class = 0; class < list[i].num_classes; class++)
- {
- switch (pClass->class)
- {
- case ButtonClass:
- if (((XButtonInfo *) pClass)->num_buttons > 0)
- {
- /* Macros set values in the second & third arguments */
- DeviceButtonPress (dev, si->xinput_DeviceButtonPress,
- dev_info->press);
- event_list[nevents++] = dev_info->press;
-
- DeviceButtonRelease (dev, si->xinput_DeviceButtonRelease,
- dev_info->release);
- event_list[nevents++] = dev_info->release;
- device_we_want = True;
- }
- break;
-
- case ValuatorClass:
- if (((XValuatorInfo *) pClass)->num_axes > 0)
- {
- DeviceMotionNotify (dev, si->xinput_DeviceMotionNotify,
- dev_info->valuator);
- event_list[nevents++] = dev_info->valuator;
- device_we_want = True;
- }
- break;
-
- default:
- /* ignore other classes of devices/events */
- break;
- }
-
- pClass = (XAnyClassPtr) & ((char *) pClass)[pClass->length];
- }
-
- if (device_we_want)
- si->num_xinput_devices++;
- else
- XCloseDevice (si->dpy, dev);
- }
- }
-
- if (list)
- XFreeDeviceList (list);
-
- if ((nevents == 0) || (si->num_xinput_devices == 0))
- {
- free(event_list);
- free(si->xinput_devices);
- si->xinput_devices = NULL;
- si->num_xinput_devices = 0;
- return;
- }
-
- for (i = 0; i < si->nscreens; i++)
- {
- saver_screen_info *ssi = &si->screens[i];
- Window root = RootWindowOfScreen (ssi->screen);
- XSelectExtensionEvent (si->dpy, root, event_list, nevents);
- }
-
- free(event_list);
-}
-
-#if 0
-/* not used */
-static void
-close_xinput_extension (saver_info *si)
-{
- int i;
-
- for (i = 0; i < si->num_xinput_devices; i++)
- XCloseDevice (si->dpy, si->xinput_devices[i].device);
-
- free(si->xinput_devices);
- si->xinput_devices = NULL;
- si->num_xinput_devices = 0;
-}
-#endif
-#endif /* HAVE_XINPUT */
-
-
-/* SGI SCREEN_SAVER server extension hackery.
- */
-
-#ifdef HAVE_SGI_SAVER_EXTENSION
-
-# include <X11/extensions/XScreenSaver.h>
-
-static void
-init_sgi_saver_extension (saver_info *si)
-{
- saver_preferences *p = &si->prefs;
- int i;
- if (si->screen_blanked_p)
- /* If you mess with this while the server thinks it's active,
- the server crashes. */
- return;
-
- for (i = 0; i < si->nscreens; i++)
- {
- saver_screen_info *ssi = &si->screens[i];
- XScreenSaverDisable (si->dpy, XScreenNumberOfScreen(ssi->screen));
- if (! XScreenSaverEnable (si->dpy, XScreenNumberOfScreen(ssi->screen)))
- {
- fprintf (stderr,
- "%s: SGI SCREEN_SAVER extension exists, but can't be initialized;\n\
- perhaps some other screensaver program is already running?\n",
- blurb());
- si->using_sgi_saver_extension = False;
- return;
- }
- }
-}
-
-#endif /* HAVE_SGI_SAVER_EXTENSION */
-
-
-
-/* Figuring out what the appropriate XSetScreenSaver() parameters are
- (one wouldn't expect this to be rocket science.)
- */
-
-void
-disable_builtin_screensaver (saver_info *si, Bool unblank_screen_p)
-{
- saver_preferences *p = &si->prefs;
- int current_server_timeout, current_server_interval;
- int current_prefer_blank, current_allow_exp;
- int desired_server_timeout, desired_server_interval;
- int desired_prefer_blank, desired_allow_exp;
-
- XGetScreenSaver (si->dpy, &current_server_timeout, &current_server_interval,
- &current_prefer_blank, &current_allow_exp);
-
- desired_server_timeout = current_server_timeout;
- desired_server_interval = current_server_interval;
- desired_prefer_blank = current_prefer_blank;
- desired_allow_exp = current_allow_exp;
-
- /* On SGIs, if interval is non-zero, it is the number of seconds after
- screen saving starts at which the monitor should be powered down.
- Obviously I don't want that, so set it to 0 (meaning "never".)
-
- Power saving is disabled if DontPreferBlanking, but in that case,
- we don't get extension events either. So we can't turn it off that way.
-
- Note: if you're running Irix 6.3 (O2), you may find that your monitor is
- powering down anyway, regardless of the xset settings. This is fixed by
- installing SGI patches 2447 and 2537.
- */
- desired_server_interval = 0;
-
- /* I suspect (but am not sure) that DontAllowExposures might have
- something to do with powering off the monitor as well, at least
- on some systems that don't support XDPMS? Who knows... */
- desired_allow_exp = AllowExposures;
-
- if (si->using_mit_saver_extension || si->using_sgi_saver_extension)
- {
- desired_server_timeout = (p->timeout / 1000);
-
- /* The SGI extension won't give us events unless blanking is on.
- I think (unsure right now) that the MIT extension is the opposite. */
- if (si->using_sgi_saver_extension)
- desired_prefer_blank = PreferBlanking;
- else
- desired_prefer_blank = DontPreferBlanking;
- }
- else
- {
- /* When we're not using an extension, set the server-side timeout to 0,
- so that the server never gets involved with screen blanking, and we
- do it all ourselves. (However, when we *are* using an extension,
- we tell the server when to notify us, and rather than blanking the
- screen, the server will send us an X event telling us to blank.)
- */
- desired_server_timeout = 0;
- }
-
- /* XSetScreenSaver() generates BadValue if either timeout parameter
- exceeds 15 bits (signed short.) That is 09:06:07.
- */
- if (desired_server_timeout > 0x7FFF) desired_server_timeout = 0x7FFF;
- if (desired_server_interval > 0x7FFF) desired_server_interval = 0x7FFF;
-
- if (desired_server_timeout != current_server_timeout ||
- desired_server_interval != current_server_interval ||
- desired_prefer_blank != current_prefer_blank ||
- desired_allow_exp != current_allow_exp)
- {
- if (p->verbose_p)
- fprintf (stderr,
- "%s: disabling server builtin screensaver:\n"
- "%s: (xset s %d %d; xset s %s; xset s %s)\n",
- blurb(), blurb(),
- desired_server_timeout, desired_server_interval,
- (desired_prefer_blank ? "blank" : "noblank"),
- (desired_allow_exp ? "expose" : "noexpose"));
-
- XSetScreenSaver (si->dpy,
- desired_server_timeout, desired_server_interval,
- desired_prefer_blank, desired_allow_exp);
- XSync(si->dpy, False);
- }
-
-
-#if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
- {
- static Bool extension_initted = False;
- if (!extension_initted)
- {
- extension_initted = True;
-# ifdef HAVE_MIT_SAVER_EXTENSION
- if (si->using_mit_saver_extension) init_mit_saver_extension(si);
-# endif
-# ifdef HAVE_SGI_SAVER_EXTENSION
- if (si->using_sgi_saver_extension) init_sgi_saver_extension(si);
-# endif
- }
- }
-#endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
-
- if (unblank_screen_p)
- /* Turn off the server builtin saver if it is now running. */
- XForceScreenSaver (si->dpy, ScreenSaverReset);
-}
diff --git a/utils/fade.c b/utils/fade.c
deleted file mode 100644
index 7a2ce2b..0000000
--- a/utils/fade.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/* xscreensaver, Copyright (c) 1992-2011 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-#include "utils.h"
-
-#include <sys/time.h> /* for gettimeofday() */
-
-#ifdef VMS
-# include "vms-gtod.h"
-#endif /* VMS */
-
-#include "visual.h"
-#include "usleep.h"
-#include "fade.h"
-
-Colormap
-copy_colormap (Screen *screen, Visual *visual,
- Colormap cmap, Colormap into_cmap)
-{
- int i;
- Display *dpy = DisplayOfScreen (screen);
- Window window = RootWindowOfScreen (screen);
- int ncolors = CellsOfScreen (screen);
- XColor *colors = 0;
-
- /* If this is a colormap on a mono visual, or one with insanely many
- color cells, bug out. */
- if (ncolors <= 2 || ncolors > 4096)
- return 0;
- /* If this is a non-writable visual, bug out. */
- if (!has_writable_cells (screen, visual))
- return 0;
-
- if (! into_cmap)
- into_cmap = XCreateColormap (dpy, window, visual, AllocAll);
- if (! cmap)
- cmap = DefaultColormapOfScreen (screen);
-
- colors = (XColor *) calloc(sizeof(XColor), ncolors);
- for (i = 0; i < ncolors; i++)
- colors [i].pixel = i;
- XQueryColors (dpy, cmap, colors, ncolors);
- XStoreColors (dpy, into_cmap, colors, ncolors);
- free (colors);
- return into_cmap;
-}
-
-
-void
-blacken_colormap (Screen *screen, Colormap cmap)
-{
- Display *dpy = DisplayOfScreen (screen);
- int ncolors = CellsOfScreen (screen);
- XColor *colors;
- int i;
- if (ncolors > 4096)
- return;
- colors = (XColor *) calloc(sizeof(XColor), ncolors);
- for (i = 0; i < ncolors; i++)
- colors[i].pixel = i;
- XStoreColors (dpy, cmap, colors, ncolors);
- free (colors);
-}
-
-
-
-static void fade_screens_1 (Display *dpy, Colormap *cmaps,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows);
-
-#ifdef HAVE_SGI_VC_EXTENSION
-static int sgi_gamma_fade (Display *dpy,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows);
-#endif /* HAVE_SGI_VC_EXTENSION */
-
-#ifdef HAVE_XF86VMODE_GAMMA
-static int xf86_gamma_fade (Display *dpy,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows);
-#endif /* HAVE_XF86VMODE_GAMMA */
-
-
-void
-fade_screens (Display *dpy, Colormap *cmaps,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows)
-{
- int oseconds = seconds;
- Bool was_in_p = !out_p;
-
- /* When we're asked to fade in, first fade out, then fade in.
- That way all the transitions are smooth -- from what's on the
- screen, to black, to the desktop.
- */
- if (was_in_p)
- {
- clear_windows = True;
- out_p = True;
- seconds /= 3;
- if (seconds == 0)
- seconds = 1;
- }
-
- AGAIN:
-
-/* #### printf("\n\nfade_screens %d %d %d\n", seconds, ticks, out_p); */
-
-#ifdef HAVE_SGI_VC_EXTENSION
- /* First try to do it by fading the gamma in an SGI-specific way... */
- if (0 == sgi_gamma_fade(dpy, black_windows, nwindows,
- seconds, ticks, out_p,
- clear_windows))
- ;
- else
-#endif /* HAVE_SGI_VC_EXTENSION */
-
-#ifdef HAVE_XF86VMODE_GAMMA
- /* Then try to do it by fading the gamma in an XFree86-specific way... */
- if (0 == xf86_gamma_fade(dpy, black_windows, nwindows,
- seconds, ticks, out_p,
- clear_windows))
- ;
- else
-#endif /* HAVE_XF86VMODE_GAMMA */
-
- /* Else, do it the old-fashioned way, which (somewhat) loses if
- there are TrueColor windows visible. */
- fade_screens_1 (dpy, cmaps, black_windows, nwindows,
- seconds, ticks,
- out_p, clear_windows);
-
- /* If we were supposed to be fading in, do so now (we just faded out,
- so now fade back in.)
- */
- if (was_in_p)
- {
- was_in_p = False;
- out_p = False;
- seconds = oseconds * 2 / 3;
- if (seconds == 0)
- seconds = 1;
- goto AGAIN;
- }
-}
-
-
-static void
-sleep_from (struct timeval *now, struct timeval *then, long usecs_per_step)
-{
- /* If several seconds have passed, the machine must have been asleep
- or thrashing or something. Don't sleep in that case, to avoid
- overflowing and sleeping for an unconscionably long time. This
- function should only be sleeping for very short periods.
- */
- if (now->tv_sec - then->tv_sec < 5)
- {
- long diff = (((now->tv_sec - then->tv_sec) * 1000000) +
- now->tv_usec - then->tv_usec);
- if (usecs_per_step > diff)
- usleep (usecs_per_step - diff);
- }
-
- then->tv_sec = now->tv_sec;
- then->tv_usec = now->tv_usec;
-}
-
-
-
-/* The business with `cmaps_per_screen' is to fake out the SGI 8-bit video
- hardware, which is capable of installing multiple (4) colormaps
- simultaneously. We have to install multiple copies of the same set of
- colors in order to fill up all the available slots in the hardware color
- lookup table, so we install an extra N colormaps per screen to make sure
- that all screens really go black.
-
- I'm told that this trick also works with XInside's AcceleratedX when using
- the Matrox Millennium card (which also allows multiple PseudoColor and
- TrueColor visuals to co-exist and display properly at the same time.)
-
- This trick works ok on the 24-bit Indy video hardware, but doesn't work at
- all on the O2 24-bit hardware. I guess the higher-end hardware is too
- "good" for this to work (dammit.) So... I figured out the "right" way to
- do this on SGIs, which is to ramp the monitor's gamma down to 0. That's
- what is implemented in sgi_gamma_fade(), so we use that if we can.
- */
-static void
-fade_screens_1 (Display *dpy, Colormap *cmaps,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows)
-{
- int i, j, k;
- int steps = seconds * ticks;
- long usecs_per_step = (long)(seconds * 1000000) / (long)steps;
- XEvent dummy_event;
- int cmaps_per_screen = 5;
- int nscreens = ScreenCount(dpy);
- int ncmaps = nscreens * cmaps_per_screen;
- Colormap *fade_cmaps = 0;
- Bool installed = False;
- int total_ncolors;
- XColor *orig_colors, *current_colors, *screen_colors, *orig_screen_colors;
- struct timeval then, now;
-#ifdef GETTIMEOFDAY_TWO_ARGS
- struct timezone tzp;
-#endif
-
- total_ncolors = 0;
- for (i = 0; i < nscreens; i++)
- total_ncolors += CellsOfScreen (ScreenOfDisplay(dpy, i));
-
- orig_colors = (XColor *) calloc(sizeof(XColor), total_ncolors);
- current_colors = (XColor *) calloc(sizeof(XColor), total_ncolors);
-
- /* Get the contents of the colormap we are fading from or to. */
- screen_colors = orig_colors;
- for (i = 0; i < nscreens; i++)
- {
- int ncolors = CellsOfScreen (ScreenOfDisplay (dpy, i));
- Colormap cmap = (cmaps ? cmaps[i] : 0);
- if (!cmap) cmap = DefaultColormap(dpy, i);
-
- for (j = 0; j < ncolors; j++)
- screen_colors[j].pixel = j;
- XQueryColors (dpy, cmap, screen_colors, ncolors);
-
- screen_colors += ncolors;
- }
-
- memcpy (current_colors, orig_colors, total_ncolors * sizeof (XColor));
-
-
- /* Make the writable colormaps (we keep these around and reuse them.) */
- if (!fade_cmaps)
- {
- fade_cmaps = (Colormap *) calloc(sizeof(Colormap), ncmaps);
- for (i = 0; i < nscreens; i++)
- {
- Visual *v = DefaultVisual(dpy, i);
- Screen *s = ScreenOfDisplay(dpy, i);
- if (has_writable_cells (s, v))
- for (j = 0; j < cmaps_per_screen; j++)
- fade_cmaps[(i * cmaps_per_screen) + j] =
- XCreateColormap (dpy, RootWindowOfScreen (s), v, AllocAll);
- }
- }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
- gettimeofday(&then, &tzp);
-#else
- gettimeofday(&then);
-#endif
-
- /* Iterate by steps of the animation... */
- for (i = (out_p ? steps : 0);
- (out_p ? i > 0 : i < steps);
- (out_p ? i-- : i++))
- {
-
- /* For each screen, compute the current value of each color...
- */
- orig_screen_colors = orig_colors;
- screen_colors = current_colors;
- for (j = 0; j < nscreens; j++)
- {
- int ncolors = CellsOfScreen (ScreenOfDisplay (dpy, j));
- for (k = 0; k < ncolors; k++)
- {
- /* This doesn't take into account the relative luminance of the
- RGB components (0.299, 0.587, and 0.114 at gamma 2.2) but
- the difference is imperceptible for this application... */
- screen_colors[k].red = orig_screen_colors[k].red * i / steps;
- screen_colors[k].green = orig_screen_colors[k].green * i / steps;
- screen_colors[k].blue = orig_screen_colors[k].blue * i / steps;
- }
- screen_colors += ncolors;
- orig_screen_colors += ncolors;
- }
-
- /* Put the colors into the maps...
- */
- screen_colors = current_colors;
- for (j = 0; j < nscreens; j++)
- {
- int ncolors = CellsOfScreen (ScreenOfDisplay (dpy, j));
- for (k = 0; k < cmaps_per_screen; k++)
- {
- Colormap c = fade_cmaps[j * cmaps_per_screen + k];
- if (c)
- XStoreColors (dpy, c, screen_colors, ncolors);
- }
- screen_colors += ncolors;
- }
-
- /* Put the maps on the screens, and then take the windows off the screen.
- (only need to do this the first time through the loop.)
- */
- if (!installed)
- {
- for (j = 0; j < ncmaps; j++)
- if (fade_cmaps[j])
- XInstallColormap (dpy, fade_cmaps[j]);
- installed = True;
-
- if (black_windows && !out_p)
- for (j = 0; j < nwindows; j++)
- if (black_windows[j])
- {
- XUnmapWindow (dpy, black_windows[j]);
- XClearWindow (dpy, black_windows[j]);
- }
- }
-
- XSync (dpy, False);
-
- /* If there is user activity, bug out. (Bug out on keypresses or
- mouse presses, but not motion, and not release events. Bugging
- out on motion made the unfade hack be totally useless, I think.)
-
- We put the event back so that the calling code can notice it too.
- It would be better to not remove it at all, but that's harder
- because Xlib has such a non-design for this kind of crap, and
- in this application it doesn't matter if the events end up out
- of order, so in the grand unix tradition we say "fuck it" and
- do something that mostly works for the time being.
- */
- if (XCheckMaskEvent (dpy, (KeyPressMask|ButtonPressMask), &dummy_event))
- {
- XPutBackEvent (dpy, &dummy_event);
- goto DONE;
- }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
- gettimeofday(&now, &tzp);
-#else
- gettimeofday(&now);
-#endif
-
- /* If we haven't already used up our alotted time, sleep to avoid
- changing the colormap too fast. */
- sleep_from (&now, &then, usecs_per_step);
- }
-
- DONE:
-
- if (orig_colors) free (orig_colors);
- if (current_colors) free (current_colors);
-
- /* If we've been given windows to raise after blackout, raise them before
- releasing the colormaps.
- */
- if (out_p && black_windows)
- {
- for (i = 0; i < nwindows; i++)
- {
- if (clear_windows)
- XClearWindow (dpy, black_windows[i]);
- XMapRaised (dpy, black_windows[i]);
- }
- XSync(dpy, False);
- }
-
- /* Now put the target maps back.
- If we're fading out, use the given cmap (or the default cmap, if none.)
- If we're fading in, always use the default cmap.
- */
- for (i = 0; i < nscreens; i++)
- {
- Colormap cmap = (cmaps ? cmaps[i] : 0);
- if (!cmap || !out_p)
- cmap = DefaultColormap(dpy, i);
- XInstallColormap (dpy, cmap);
- }
-
- /* The fade (in or out) is complete, so we don't need the black maps on
- stage any more.
- */
- for (i = 0; i < ncmaps; i++)
- if (fade_cmaps[i])
- {
- XUninstallColormap(dpy, fade_cmaps[i]);
- XFreeColormap(dpy, fade_cmaps[i]);
- fade_cmaps[i] = 0;
- }
- free(fade_cmaps);
- fade_cmaps = 0;
-}
-
-
-
-/* SGI Gamma fading */
-
-#ifdef HAVE_SGI_VC_EXTENSION
-
-# include <X11/extensions/XSGIvc.h>
-
-struct screen_sgi_gamma_info {
- int gamma_map; /* ??? always using 0 */
- int nred, ngreen, nblue;
- unsigned short *red1, *green1, *blue1;
- unsigned short *red2, *green2, *blue2;
- int gamma_size;
- int gamma_precision;
- Bool alpha_p;
-};
-
-
-static void sgi_whack_gamma(Display *dpy, int screen,
- struct screen_sgi_gamma_info *info, float ratio);
-
-static int
-sgi_gamma_fade (Display *dpy,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows)
-{
- int steps = seconds * ticks;
- long usecs_per_step = (long)(seconds * 1000000) / (long)steps;
- XEvent dummy_event;
- int nscreens = ScreenCount(dpy);
- struct timeval then, now;
-#ifdef GETTIMEOFDAY_TWO_ARGS
- struct timezone tzp;
-#endif
- int i, screen;
- int status = -1;
- struct screen_sgi_gamma_info *info = (struct screen_sgi_gamma_info *)
- calloc(nscreens, sizeof(*info));
-
- /* Get the current gamma maps for all screens.
- Bug out and return -1 if we can't get them for some screen.
- */
- for (screen = 0; screen < nscreens; screen++)
- {
- if (!XSGIvcQueryGammaMap(dpy, screen, info[screen].gamma_map,
- &info[screen].gamma_size,
- &info[screen].gamma_precision,
- &info[screen].alpha_p))
- goto FAIL;
-
- if (!XSGIvcQueryGammaColors(dpy, screen, info[screen].gamma_map,
- XSGIVC_COMPONENT_RED,
- &info[screen].nred, &info[screen].red1))
- goto FAIL;
- if (! XSGIvcQueryGammaColors(dpy, screen, info[screen].gamma_map,
- XSGIVC_COMPONENT_GREEN,
- &info[screen].ngreen, &info[screen].green1))
- goto FAIL;
- if (!XSGIvcQueryGammaColors(dpy, screen, info[screen].gamma_map,
- XSGIVC_COMPONENT_BLUE,
- &info[screen].nblue, &info[screen].blue1))
- goto FAIL;
-
- if (info[screen].gamma_precision == 8) /* Scale it up to 16 bits. */
- {
- int j;
- for(j = 0; j < info[screen].nred; j++)
- info[screen].red1[j] =
- ((info[screen].red1[j] << 8) | info[screen].red1[j]);
- for(j = 0; j < info[screen].ngreen; j++)
- info[screen].green1[j] =
- ((info[screen].green1[j] << 8) | info[screen].green1[j]);
- for(j = 0; j < info[screen].nblue; j++)
- info[screen].blue1[j] =
- ((info[screen].blue1[j] << 8) | info[screen].blue1[j]);
- }
-
- info[screen].red2 = (unsigned short *)
- malloc(sizeof(*info[screen].red2) * (info[screen].nred+1));
- info[screen].green2 = (unsigned short *)
- malloc(sizeof(*info[screen].green2) * (info[screen].ngreen+1));
- info[screen].blue2 = (unsigned short *)
- malloc(sizeof(*info[screen].blue2) * (info[screen].nblue+1));
- }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
- gettimeofday(&then, &tzp);
-#else
- gettimeofday(&then);
-#endif
-
- /* If we're fading in (from black), then first crank the gamma all the
- way down to 0, then take the windows off the screen.
- */
- if (!out_p)
- {
- for (screen = 0; screen < nscreens; screen++)
- sgi_whack_gamma(dpy, screen, &info[screen], 0.0);
-
- for (screen = 0; screen < nwindows; screen++)
- if (black_windows && black_windows[screen])
- {
- XUnmapWindow (dpy, black_windows[screen]);
- XClearWindow (dpy, black_windows[screen]);
- XSync(dpy, False);
- }
- }
-
- /* Iterate by steps of the animation... */
- for (i = (out_p ? steps : 0);
- (out_p ? i > 0 : i < steps);
- (out_p ? i-- : i++))
- {
- for (screen = 0; screen < nscreens; screen++)
- {
- sgi_whack_gamma(dpy, screen, &info[screen],
- (((float)i) / ((float)steps)));
-
- /* If there is user activity, bug out. (Bug out on keypresses or
- mouse presses, but not motion, and not release events. Bugging
- out on motion made the unfade hack be totally useless, I think.)
-
- We put the event back so that the calling code can notice it too.
- It would be better to not remove it at all, but that's harder
- because Xlib has such a non-design for this kind of crap, and
- in this application it doesn't matter if the events end up out
- of order, so in the grand unix tradition we say "fuck it" and
- do something that mostly works for the time being.
- */
- if (XCheckMaskEvent (dpy, (KeyPressMask|ButtonPressMask),
- &dummy_event))
- {
- XPutBackEvent (dpy, &dummy_event);
- goto DONE;
- }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
- gettimeofday(&now, &tzp);
-#else
- gettimeofday(&now);
-#endif
-
- /* If we haven't already used up our alotted time, sleep to avoid
- changing the colormap too fast. */
- sleep_from (&now, &then, usecs_per_step);
- }
- }
-
-
- DONE:
-
- if (out_p && black_windows)
- {
- for (screen = 0; screen < nwindows; screen++)
- {
- if (clear_windows)
- XClearWindow (dpy, black_windows[screen]);
- XMapRaised (dpy, black_windows[screen]);
- }
- XSync(dpy, False);
- }
-
- /* I can't explain this; without this delay, we get a flicker.
- I suppose there's some lossage with stale bits being in the
- hardware frame buffer or something, and this delay gives it
- time to flush out. This sucks! */
- usleep(100000); /* 1/10th second */
-
- for (screen = 0; screen < nscreens; screen++)
- sgi_whack_gamma(dpy, screen, &info[screen], 1.0);
- XSync(dpy, False);
-
- status = 0;
-
- FAIL:
- for (screen = 0; screen < nscreens; screen++)
- {
- if (info[screen].red1) free (info[screen].red1);
- if (info[screen].green1) free (info[screen].green1);
- if (info[screen].blue1) free (info[screen].blue1);
- if (info[screen].red2) free (info[screen].red2);
- if (info[screen].green2) free (info[screen].green2);
- if (info[screen].blue2) free (info[screen].blue2);
- }
- free(info);
-
- return status;
-}
-
-static void
-sgi_whack_gamma(Display *dpy, int screen, struct screen_sgi_gamma_info *info,
- float ratio)
-{
- int k;
-
- if (ratio < 0) ratio = 0;
- if (ratio > 1) ratio = 1;
- for (k = 0; k < info->gamma_size; k++)
- {
- info->red2[k] = info->red1[k] * ratio;
- info->green2[k] = info->green1[k] * ratio;
- info->blue2[k] = info->blue1[k] * ratio;
- }
-
- XSGIvcStoreGammaColors16(dpy, screen, info->gamma_map, info->nred,
- XSGIVC_MComponentRed, info->red2);
- XSGIvcStoreGammaColors16(dpy, screen, info->gamma_map, info->ngreen,
- XSGIVC_MComponentGreen, info->green2);
- XSGIvcStoreGammaColors16(dpy, screen, info->gamma_map, info->nblue,
- XSGIVC_MComponentBlue, info->blue2);
- XSync(dpy, False);
-}
-
-#endif /* HAVE_SGI_VC_EXTENSION */
-
-
-
-/* XFree86 4.x+ Gamma fading */
-
-#ifdef HAVE_XF86VMODE_GAMMA
-
-#include <X11/extensions/xf86vmode.h>
-
-typedef struct {
- XF86VidModeGamma vmg;
- int size;
- unsigned short *r, *g, *b;
-} xf86_gamma_info;
-
-static int xf86_check_gamma_extension (Display *dpy);
-static Bool xf86_whack_gamma (Display *dpy, int screen,
- xf86_gamma_info *ginfo, float ratio);
-
-static int
-xf86_gamma_fade (Display *dpy,
- Window *black_windows, int nwindows,
- int seconds, int ticks,
- Bool out_p, Bool clear_windows)
-{
- int steps = seconds * ticks;
- long usecs_per_step = (long)(seconds * 1000000) / (long)steps;
- XEvent dummy_event;
- int nscreens = ScreenCount(dpy);
- struct timeval then, now;
-#ifdef GETTIMEOFDAY_TWO_ARGS
- struct timezone tzp;
-#endif
- int i, screen;
- int status = -1;
- xf86_gamma_info *info = 0;
-
- static int ext_ok = -1;
-
- /* Only probe the extension once: the answer isn't going to change. */
- if (ext_ok == -1)
- ext_ok = xf86_check_gamma_extension (dpy);
-
- /* If this server doesn't have the gamma extension, bug out. */
- if (ext_ok == 0)
- goto FAIL;
-
-# ifndef HAVE_XF86VMODE_GAMMA_RAMP
- if (ext_ok == 2) ext_ok = 1; /* server is newer than client! */
-# endif
-
- info = (xf86_gamma_info *) calloc(nscreens, sizeof(*info));
-
- /* Get the current gamma maps for all screens.
- Bug out and return -1 if we can't get them for some screen.
- */
- for (screen = 0; screen < nscreens; screen++)
- {
- if (ext_ok == 1) /* only have gamma parameter, not ramps. */
- {
- if (!XF86VidModeGetGamma(dpy, screen, &info[screen].vmg))
- goto FAIL;
- }
-# ifdef HAVE_XF86VMODE_GAMMA_RAMP
- else if (ext_ok == 2) /* have ramps */
- {
- if (!XF86VidModeGetGammaRampSize(dpy, screen, &info[screen].size))
- goto FAIL;
- if (info[screen].size <= 0)
- goto FAIL;
-
- info[screen].r = (unsigned short *)
- calloc(info[screen].size, sizeof(unsigned short));
- info[screen].g = (unsigned short *)
- calloc(info[screen].size, sizeof(unsigned short));
- info[screen].b = (unsigned short *)
- calloc(info[screen].size, sizeof(unsigned short));
-
- if (!(info[screen].r && info[screen].g && info[screen].b))
- goto FAIL;
-
- if (!XF86VidModeGetGammaRamp(dpy, screen, info[screen].size,
- info[screen].r,
- info[screen].g,
- info[screen].b))
- goto FAIL;
- }
-# endif /* HAVE_XF86VMODE_GAMMA_RAMP */
- else
- abort();
- }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
- gettimeofday(&then, &tzp);
-#else
- gettimeofday(&then);
-#endif
-
- /* If we're fading in (from black), then first crank the gamma all the
- way down to 0, then take the windows off the screen.
- */
- if (!out_p)
- {
- for (screen = 0; screen < nscreens; screen++)
- xf86_whack_gamma(dpy, screen, &info[screen], 0.0);
- for (screen = 0; screen < nwindows; screen++)
- if (black_windows && black_windows[screen])
- {
- XUnmapWindow (dpy, black_windows[screen]);
- XClearWindow (dpy, black_windows[screen]);
- XSync(dpy, False);
- }
- }
-
- /* Iterate by steps of the animation... */
- for (i = (out_p ? steps : 0);
- (out_p ? i > 0 : i < steps);
- (out_p ? i-- : i++))
- {
- for (screen = 0; screen < nscreens; screen++)
- {
- xf86_whack_gamma(dpy, screen, &info[screen],
- (((float)i) / ((float)steps)));
-
- /* If there is user activity, bug out. (Bug out on keypresses or
- mouse presses, but not motion, and not release events. Bugging
- out on motion made the unfade hack be totally useless, I think.)
-
- We put the event back so that the calling code can notice it too.
- It would be better to not remove it at all, but that's harder
- because Xlib has such a non-design for this kind of crap, and
- in this application it doesn't matter if the events end up out
- of order, so in the grand unix tradition we say "fuck it" and
- do something that mostly works for the time being.
- */
- if (XCheckMaskEvent (dpy, (KeyPressMask|ButtonPressMask),
- &dummy_event))
- {
- XPutBackEvent (dpy, &dummy_event);
- goto DONE;
- }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
- gettimeofday(&now, &tzp);
-#else
- gettimeofday(&now);
-#endif
-
- /* If we haven't already used up our alotted time, sleep to avoid
- changing the colormap too fast. */
- sleep_from (&now, &then, usecs_per_step);
- }
- }
-
-
- DONE:
-
- if (out_p && black_windows)
- {
- for (screen = 0; screen < nwindows; screen++)
- {
- if (clear_windows)
- XClearWindow (dpy, black_windows[screen]);
- XMapRaised (dpy, black_windows[screen]);
- }
- XSync(dpy, False);
- }
-
- /* I can't explain this; without this delay, we get a flicker.
- I suppose there's some lossage with stale bits being in the
- hardware frame buffer or something, and this delay gives it
- time to flush out. This sucks! */
- usleep(100000); /* 1/10th second */
-
- for (screen = 0; screen < nscreens; screen++)
- xf86_whack_gamma(dpy, screen, &info[screen], 1.0);
- XSync(dpy, False);
-
- status = 0;
-
- FAIL:
- if (info)
- {
- for (screen = 0; screen < nscreens; screen++)
- {
- if (info[screen].r) free(info[screen].r);
- if (info[screen].g) free(info[screen].g);
- if (info[screen].b) free(info[screen].b);
- }
- free(info);
- }
-
- return status;
-}
-
-
-/* This bullshit is needed because the VidMode extension doesn't work
- on remote displays -- but if the remote display has the extension
- at all, XF86VidModeQueryExtension returns true, and then
- XF86VidModeQueryVersion dies with an X error. Thank you XFree,
- may I have another.
- */
-
-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 Bool
-safe_XF86VidModeQueryVersion (Display *dpy, int *majP, int *minP)
-{
- Bool result;
- XErrorHandler old_handler;
- XSync (dpy, False);
- error_handler_hit_p = False;
- old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
-
- result = XF86VidModeQueryVersion (dpy, majP, minP);
-
- XSync (dpy, False);
- XSetErrorHandler (old_handler);
- XSync (dpy, False);
-
- return (error_handler_hit_p
- ? False
- : result);
-}
-
-
-
-/* VidModeExtension version 2.0 or better is needed to do gamma.
- 2.0 added gamma values; 2.1 added gamma ramps.
- */
-# define XF86_VIDMODE_GAMMA_MIN_MAJOR 2
-# define XF86_VIDMODE_GAMMA_MIN_MINOR 0
-# define XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR 2
-# define XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR 1
-
-
-
-/* Returns 0 if gamma fading not available; 1 if only gamma value setting
- is available; 2 if gamma ramps are available.
- */
-static int
-xf86_check_gamma_extension (Display *dpy)
-{
- int event, error, major, minor;
-
- if (!XF86VidModeQueryExtension (dpy, &event, &error))
- return 0; /* display doesn't have the extension. */
-
- if (!safe_XF86VidModeQueryVersion (dpy, &major, &minor))
- return 0; /* unable to get version number? */
-
- if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR ||
- (major == XF86_VIDMODE_GAMMA_MIN_MAJOR &&
- minor < XF86_VIDMODE_GAMMA_MIN_MINOR))
- return 0; /* extension is too old for gamma. */
-
- if (major < XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR ||
- (major == XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR &&
- minor < XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR))
- return 1; /* extension is too old for gamma ramps. */
-
- /* Copacetic */
- return 2;
-}
-
-
-/* XFree doesn't let you set gamma to a value smaller than this.
- Apparently they didn't anticipate the trick I'm doing here...
- */
-#define XF86_MIN_GAMMA 0.1
-
-
-static Bool
-xf86_whack_gamma(Display *dpy, int screen, xf86_gamma_info *info,
- float ratio)
-{
- Bool status;
-
- XErrorHandler old_handler;
- XSync (dpy, False);
- error_handler_hit_p = False;
- old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
-
- if (ratio < 0) ratio = 0;
- if (ratio > 1) ratio = 1;
-
- if (info->size == 0) /* we only have a gamma number, not a ramp. */
- {
- XF86VidModeGamma g2;
-
- g2.red = info->vmg.red * ratio;
- g2.green = info->vmg.green * ratio;
- g2.blue = info->vmg.blue * ratio;
-
-# ifdef XF86_MIN_GAMMA
- if (g2.red < XF86_MIN_GAMMA) g2.red = XF86_MIN_GAMMA;
- if (g2.green < XF86_MIN_GAMMA) g2.green = XF86_MIN_GAMMA;
- if (g2.blue < XF86_MIN_GAMMA) g2.blue = XF86_MIN_GAMMA;
-# endif
-
- status = XF86VidModeSetGamma (dpy, screen, &g2);
- }
- else
- {
-# ifdef HAVE_XF86VMODE_GAMMA_RAMP
-
- unsigned short *r, *g, *b;
- int i;
- r = (unsigned short *) malloc(info->size * sizeof(unsigned short));
- g = (unsigned short *) malloc(info->size * sizeof(unsigned short));
- b = (unsigned short *) malloc(info->size * sizeof(unsigned short));
-
- for (i = 0; i < info->size; i++)
- {
- r[i] = info->r[i] * ratio;
- g[i] = info->g[i] * ratio;
- b[i] = info->b[i] * ratio;
- }
-
- status = XF86VidModeSetGammaRamp(dpy, screen, info->size, r, g, b);
-
- free (r);
- free (g);
- free (b);
-
-# else /* !HAVE_XF86VMODE_GAMMA_RAMP */
- abort();
-# endif /* !HAVE_XF86VMODE_GAMMA_RAMP */
- }
-
- XSync (dpy, False);
- XSetErrorHandler (old_handler);
- XSync (dpy, False);
-
- return status;
-}
-
-#endif /* HAVE_XF86VMODE_GAMMA */
diff --git a/utils/vms-gtod.c b/utils/vms-gtod.c
deleted file mode 100644
index 7b1df5a..0000000
--- a/utils/vms-gtod.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * UNIX-style Time Functions, by pmoreau@cena.dgac.fr <Patrick MOREAU>
- * (picked up from XVMSUTILS unix emulation routines for VMS by
- * Trevor Taylor, Patrick Mahans and Martin P.J. Zinser)
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, 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 <stdio.h>
-#include <signal.h>
-#include <time.h>
-#include "vms-gtod.h"
-
-/*
- * gettimeofday(2) - Returns the current time
- */
-
-int gettimeofday(tv)
-struct timeval *tv;
-{
- timeb_t tmp_time;
- ftime(&tmp_time);
- tv->tv_sec = tmp_time.time;
- tv->tv_usec = tmp_time.millitm * 1000;
- return (0);
-}
diff --git a/utils/vms-gtod.h b/utils/vms-gtod.h
deleted file mode 100644
index ffd6586..0000000
--- a/utils/vms-gtod.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* @(#)time.h 2.9 87/01/17 SMI; from UCB 7.1 6/4/86 */
-
-/*
- Definitions of various structures used on UNIX for
- time-related syscalls.
-*/
-
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef _VMS_GTOD_
-#define _VMS_GTOD_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-#ifndef __DECC
-struct timeval
-{
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-#else
-#if __DECC_VER < 50200000
-struct timeval
-{
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-#endif /* __DECC_VER */
-#endif /* __DECC */
-
-/*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-#ifndef __DECC
-struct itimerval
-{
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-#else
-#if __DECC_VER < 50200000
-struct itimerval
-{
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-#endif /* __DECC_VER */
-#endif /* __DECC */
-
-#ifndef KERNEL
-#include <time.h>
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*!_VMS_GTOD_*/
-
diff --git a/utils/vms-strdup.c b/utils/vms-strdup.c
deleted file mode 100644
index 1afc257..0000000
--- a/utils/vms-strdup.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * strdup.c
- *
- * Simple version of strdup for machines without it (ie DEC Ultrix 4.2)
- * Apparently VMS only got strdup in 1995 (v5.2...)
- *
- * By David Chatterton
- * 29 July 1993
- *
- * You can do anything you like to this... :)
- * I've stolen it from xpilot and added it to the xvmstuils MPJZ ;-)
- */
-
-#if (__VMS_VER < 70000000)
-#include <stdlib.h>
-#include <string.h>
-
-char* strdup (const char* s1)
-{
- char* s2;
- if (s2 = (char*)malloc(strlen(s1)+1))
- strcpy(s2,s1);
- return s2;
-}
-#endif