Cleaned up browser support for full-screen and pointer-locking in the Video component, and reduced the default scale factor for mouse movement events from 1.0 to 0.5, since modern screens are generally much higher resolution

This commit is contained in:
Jeff Parsons 2017-08-02 10:37:45 -07:00 committed by Jeff Parsons
commit a3c252bf99
24 changed files with 4060 additions and 4000 deletions

View file

@ -65,8 +65,8 @@ class ChipSet extends Component {
* As support for IBM-compatible machines grows, we should refrain from adding new model strings (eg, "att6300")
* and corresponding model checks, and instead add more ChipSet configuration properties, such as:
*
* pit1port: 0x48 to enable PIT1 at base port 0x48 (as used by COMPAQ_DESKPRO386); default to undefined
* kbdchip: 8041 to select 8041 emulation (eg, for ATT_6300); default to 8255 for MODEL_5150/MODEL_5160, 8042 for MODEL_5170
* portPIT1: 0x48 to enable PIT1 at base port 0x48 (as used by COMPAQ_DESKPRO386); default to undefined
* chipKBD: 8041 to select 8041 emulation (eg, for ATT_6300); default to 8255 for MODEL_5150/MODEL_5160, 8042 for MODEL_5170
*
* @this {ChipSet}
* @param {Object} parmsChipSet
@ -1063,7 +1063,7 @@ class ChipSet extends Component {
/**
* start()
*
* Notification from the CPU that it's starting.
* Notification from the Computer that it's starting.
*
* @this {ChipSet}
*/
@ -1078,7 +1078,7 @@ class ChipSet extends Component {
/**
* stop()
*
* Notification from the CPU that it's stopping.
* Notification from the Computer that it's stopping.
*
* @this {ChipSet}
*/
@ -3394,11 +3394,11 @@ class ChipSet extends Component {
* break any code (eg, the ROM BIOS diagnostics) that assumes that the timers are ticking once every 4 cycles
* (or more like every 5 cycles on a 6Mhz 80286).
*
* So, when using a machine with the ChipSet "scaletimers" property set, make sure you reset the machine's
* So, when using a machine with the ChipSet "scaleTimers" property set, make sure you reset the machine's
* speed prior to rebooting, otherwise you're likely to see ROM BIOS errors. Ditto for any application code
* that makes similar assumptions about the relationship between CPU and timer speeds.
*
* In general, you're probably better off NOT using the "scaletimers" property, and simply allowing the timers
* In general, you're probably better off NOT using the "scaleTimers" property, and simply allowing the timers
* to tick faster as you increase CPU speed (which is why fScaleTimers defaults to false).
*/
var nCycles = this.cpu.getCycles(this.fScaleTimers);

View file

@ -2206,9 +2206,8 @@ class Video extends Component {
{
super("Video", parmsVideo, Messages.VIDEO);
var video = this;
var video = this, sProp, sEvent;
this.fGecko = Web.isUserAgent("Gecko/");
var i, sEvent, asWebPrefixes = ['', 'moz', 'ms', 'webkit'];
/*
* This records the model specified (eg, "mda", "cga", "ega", "vga" or "" if none specified);
@ -2285,18 +2284,8 @@ class Video extends Component {
var sSmoothing = Web.getURLParm('smoothing');
if (sSmoothing) fSmoothing = (sSmoothing == "true");
if (fSmoothing != null) {
for (i = 0; i < asWebPrefixes.length; i++) {
sEvent = asWebPrefixes[i];
if (!sEvent) {
sEvent = 'imageSmoothingEnabled';
} else {
sEvent += 'ImageSmoothingEnabled';
}
if (this.contextScreen[sEvent] !== undefined) {
this.contextScreen[sEvent] = fSmoothing;
break;
}
}
sProp = Web.findProperty(this.contextScreen, 'imageSmoothingEnabled');
if (sProp) this.contextScreen[sProp] = fSmoothing;
}
/*
@ -2350,42 +2339,33 @@ class Video extends Component {
/*
* Here's the gross code to handle full-screen support across all supported browsers. The lack of standards
* is exasperating; browsers can't agree on 'full' or 'Full, 'request' or 'Request', 'screen' or 'Screen', and
* while some browsers honor other browser prefixes, most browsers don't.
* is exasperating; browsers can't agree on 'Fullscreen' (most common) or 'FullScreen' (least common), and while
* some browsers honor other browser prefixes, most don't. Event handlers tend to be more consistent (ie, all
* lower-case).
*/
this.container = container;
if (this.container) {
this.container.doFullScreen = container['requestFullscreen'] || container['msRequestFullscreen'] || container['mozRequestFullScreen'] || container['webkitRequestFullscreen'];
if (this.container.doFullScreen) {
for (i = 0; i < asWebPrefixes.length; i++) {
sEvent = asWebPrefixes[i] + 'fullscreenchange';
if ('on' + sEvent in document) {
var onFullScreenChange = function() {
var fFullScreen = (document['fullscreenElement'] || document['msFullscreenElement'] || document['mozFullScreenElement'] || document['webkitFullscreenElement']);
video.notifyFullScreen(!!fFullScreen);
};
document.addEventListener(sEvent, onFullScreenChange, false);
break;
}
sProp = Web.findProperty(container, 'requestFullscreen') || Web.findProperty(container, 'requestFullScreen');
if (sProp) {
this.container.doFullScreen = container[sProp];
sEvent = Web.findProperty(document, 'on', 'fullscreenchange');
if (sEvent) {
var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement');
document.addEventListener(sEvent, function onFullScreenChange() {
video.notifyFullScreen(!!sFullScreen);
}, false);
}
for (i = 0; i < asWebPrefixes.length; i++) {
sEvent = asWebPrefixes[i] + 'fullscreenerror';
if ('on' + sEvent in document) {
var onFullScreenError = function() {
video.notifyFullScreen(null);
};
document.addEventListener(sEvent, onFullScreenError, false);
break;
}
sEvent = Web.findProperty(document, 'on', 'fullscreenerror');
if (sEvent) {
document.addEventListener(sEvent, function onFullScreenError() {
video.notifyFullScreen(null);
}, false);
}
}
}
/*
* More gross code to handle pointer-locking support across all supported browsers.
*
* TODO: Consider "upgrading" this code to use the same asWebPrefixes array as above, especially once Microsoft
* finally releases a browser that supports pointer-locking (post-Windows 10?)
*/
if (this.inputScreen) {
this.inputScreen.onfocus = function onFocusScreen() {
@ -2394,37 +2374,18 @@ class Video extends Component {
this.inputScreen.onblur = function onBlurScreen() {
return video.onFocusChange(false);
};
this.inputScreen.lockPointer = this.inputScreen['requestPointerLock'] || this.inputScreen['mozRequestPointerLock'] || this.inputScreen['webkitRequestPointerLock'];
this.inputScreen.unlockPointer = this.inputScreen['exitPointerLock'] || this.inputScreen['mozExitPointerLock'] || this.inputScreen['webkitExitPointerLock'];
this.inputScreen.lockPointer = (sProp = Web.findProperty(this.inputScreen, 'requestPointerLock')) && this.inputScreen[sProp];
this.inputScreen.unlockPointer = (sProp = Web.findProperty(this.inputScreen, 'exitPointerLock')) && this.inputScreen[sProp];
if (this.inputScreen.lockPointer) {
var onPointerLockChange = function() {
var fLocked = (
document['pointerLockElement'] === video.inputScreen ||
document['mozPointerLockElement'] === video.inputScreen ||
document['webkitPointerLockElement'] === video.inputScreen);
var sPointerLock = Web.findProperty(document, 'pointerLockElement');
sEvent = Web.findProperty(document, 'on', 'pointerlockchange');
if (sEvent) document.addEventListener(sEvent, function onPointerLockChange() {
var fLocked = !!(sPointerLock && document[sPointerLock] === video.inputScreen);
video.notifyPointerLocked(fLocked);
};
if ('onpointerlockchange' in document) {
document.addEventListener('pointerlockchange', onPointerLockChange, false);
} else if ('onmozpointerlockchange' in document) {
document.addEventListener('mozpointerlockchange', onPointerLockChange, false);
} else if ('onwebkitpointerlockchange' in document) {
document.addEventListener('webkitpointerlockchange', onPointerLockChange, false);
}
}, false);
}
}
/*
* As far as overall image quality of scaled fonts, these options don't seem necessary for Safari (and
* don't have any discernible effect anyway). Turning 'webkitImageSmoothingEnabled' off DOES have an effect
* on Chrome, but it's not really a positive effect overall, so I'm leaving these off for now.
*
* if (this.contextScreen) {
* this.contextScreen['mozImageSmoothingEnabled'] = false;
* this.contextScreen['webkitImageSmoothingEnabled'] = false;
* }
*/
this.sFileURL = parmsVideo['fontROM'];
if (this.sFileURL) {
@ -2688,7 +2649,10 @@ class Video extends Component {
this.container.style.height = sHeight;
} else {
/*
* Sadly, the above code doesn't work for Firefox, because as http://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
* Sadly, the above code doesn't work for Firefox, because as:
*
* http://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
*
* explains:
*
* 'It's worth noting a key difference here between the Gecko and WebKit implementations at this time:
@ -3898,13 +3862,6 @@ class Video extends Component {
canvasFont.height = (font.cyCell << 4);
var contextFont = canvasFont.getContext("2d");
/*
* See notes above regarding ImageSmoothingEnabled....
*
contextFont['mozImageSmoothingEnabled'] = false;
contextFont['webkitImageSmoothingEnabled'] = false;
*/
var iChar, x, y;
var cyLimit = (cyChar < 8 || !offSplit)? cyChar : 8;
var imageChar = contextFont.createImageData(font.cxCell, font.cyCell);

View file

@ -100,12 +100,7 @@ class Usr {
*/
static getTimestamp()
{
var date = new Date();
var padNum = function(n)
{
return (n < 10 ? "0" : "") + n;
};
return date.getFullYear() + "-" + padNum(date.getMonth() + 1) + "-" + padNum(date.getDate()) + " " + padNum(date.getHours()) + ":" + padNum(date.getMinutes()) + ":" + padNum(date.getSeconds());
return Usr.formatDate("Y-m-d H:i:s");
}
/**

View file

@ -662,6 +662,45 @@ class Web {
return Web.isUserAgent("Mobi");
}
/**
* findProperty(obj, sProp, sSuffix)
*
* If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,
* and if a match is found, it is returned without sProp.
*
* For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,
* it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.
*
* More commonly, sSuffix is not used, so whatever property is found is returned as-is.
*
* @param {Object|null|undefined} obj
* @param {string} sProp
* @param {string} [sSuffix]
* @return {string|null}
*/
static findProperty(obj, sProp, sSuffix)
{
if (obj) {
for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {
var sName = Web.asBrowserPrefixes[i];
if (sSuffix) {
sName += sSuffix;
var sEvent = sProp + sName;
if (sEvent in obj) return sName;
} else {
if (!sName) {
sName = sProp[0].toLowerCase();
} else {
sName += sProp[0].toUpperCase();
}
sName += sProp.substr(1);
if (sName in obj) return sName;
}
}
}
return null;
}
/**
* getURLParm(sParm)
*
@ -971,6 +1010,8 @@ Web.aPageEventHandlers = {
'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)
};
Web.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];
Web.fPageLoaded = false; // set once the page's first 'onload' event has occurred
Web.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred
Web.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()

View file

@ -933,7 +933,7 @@
<xsl:variable name="scaleMouse">
<xsl:choose>
<xsl:when test="@scaleMouse"><xsl:value-of select="@scaleMouse"/></xsl:when>
<xsl:otherwise>1</xsl:otherwise>
<xsl:otherwise>0.5</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="component">