190 lines
6.2 KiB
Python
Executable file
190 lines
6.2 KiB
Python
Executable file
#! /usr/bin/env python
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
#
|
|
# Script name: mouse_and_screen_resolution.py
|
|
# Purpose: Sets mouse position and screen resolution for Windows 7 32-bit slaves
|
|
# Author(s): Zambrano Gasparnian, Armen <armenzg@mozilla.com>
|
|
# Target: Python 2.7 or newer
|
|
#
|
|
|
|
import os
|
|
import platform
|
|
import socket
|
|
import sys
|
|
import time
|
|
from ctypes import Structure, byref, c_ulong, windll
|
|
from optparse import OptionParser
|
|
|
|
try:
|
|
from urllib2 import urlopen, URLError, HTTPError
|
|
except ImportError:
|
|
from urllib.request import urlopen
|
|
from urllib.error import URLError, HTTPError
|
|
try:
|
|
import json
|
|
except:
|
|
import simplejson as json
|
|
|
|
default_screen_resolution = {"x": 1024, "y": 768}
|
|
default_mouse_position = {"x": 1010, "y": 10}
|
|
|
|
|
|
def wfetch(url, retries=5):
|
|
while True:
|
|
try:
|
|
return urlopen(url, timeout=30).read()
|
|
except HTTPError as e:
|
|
print("Failed to fetch '%s': %s" % (url, str(e)))
|
|
except URLError as e:
|
|
print("Failed to fetch '%s': %s" % (url, str(e)))
|
|
except socket.timeout as e:
|
|
print("Time out accessing %s: %s" % (url, str(e)))
|
|
except socket.error as e:
|
|
print("Socket error when accessing %s: %s" % (url, str(e)))
|
|
if retries < 0:
|
|
raise Exception("Could not fetch url '%s'" % url)
|
|
retries -= 1
|
|
print("Retrying")
|
|
time.sleep(60)
|
|
|
|
|
|
def main():
|
|
# NOTE: this script was written for windows 7, but works well with windows 10
|
|
parser = OptionParser()
|
|
parser.add_option(
|
|
"--configuration-url",
|
|
dest="configuration_url",
|
|
type="string",
|
|
help="Specifies the url of the configuration file.",
|
|
)
|
|
parser.add_option(
|
|
"--configuration-file",
|
|
dest="configuration_file",
|
|
type="string",
|
|
help="Specifies the path to the configuration file.",
|
|
)
|
|
parser.add_option(
|
|
"--platform",
|
|
dest="platform",
|
|
type="string",
|
|
default="win7",
|
|
help="Specifies the platform to coose inside the configuratoin-file.",
|
|
)
|
|
(options, args) = parser.parse_args()
|
|
|
|
if options.configuration_url == None and options.configuration_file == None:
|
|
print("You must specify --configuration-url or --configuration-file.")
|
|
return 1
|
|
|
|
if options.configuration_file:
|
|
with open(options.configuration_file) as f:
|
|
conf_dict = json.load(f)
|
|
new_screen_resolution = conf_dict[options.platform]["screen_resolution"]
|
|
new_mouse_position = conf_dict[options.platform]["mouse_position"]
|
|
else:
|
|
try:
|
|
conf_dict = json.loads(wfetch(options.configuration_url))
|
|
new_screen_resolution = conf_dict[options.platform]["screen_resolution"]
|
|
new_mouse_position = conf_dict[options.platform]["mouse_position"]
|
|
except HTTPError as e:
|
|
print(
|
|
"This branch does not seem to have the configuration file %s" % str(e)
|
|
)
|
|
print("Let's fail over to 1024x768.")
|
|
new_screen_resolution = default_screen_resolution
|
|
new_mouse_position = default_mouse_position
|
|
except URLError as e:
|
|
print("INFRA-ERROR: We couldn't reach hg.mozilla.org: %s" % str(e))
|
|
return 1
|
|
except Exception as e:
|
|
print("ERROR: We were not expecting any more exceptions: %s" % str(e))
|
|
return 1
|
|
|
|
current_screen_resolution = queryScreenResolution()
|
|
print("Screen resolution (current): (%(x)s, %(y)s)" % (current_screen_resolution))
|
|
|
|
if current_screen_resolution == new_screen_resolution:
|
|
print("No need to change the screen resolution.")
|
|
else:
|
|
print("Changing the screen resolution...")
|
|
try:
|
|
changeScreenResolution(
|
|
new_screen_resolution["x"], new_screen_resolution["y"]
|
|
)
|
|
except Exception as e:
|
|
print(
|
|
"INFRA-ERROR: We have attempted to change the screen resolution but ",
|
|
"something went wrong: %s" % str(e),
|
|
)
|
|
return 1
|
|
time.sleep(3) # just in case
|
|
current_screen_resolution = queryScreenResolution()
|
|
print("Screen resolution (new): (%(x)s, %(y)s)" % current_screen_resolution)
|
|
|
|
print("Mouse position (current): (%(x)s, %(y)s)" % (queryMousePosition()))
|
|
setCursorPos(new_mouse_position["x"], new_mouse_position["y"])
|
|
current_mouse_position = queryMousePosition()
|
|
print("Mouse position (new): (%(x)s, %(y)s)" % (current_mouse_position))
|
|
|
|
if (
|
|
current_screen_resolution != new_screen_resolution
|
|
or current_mouse_position != new_mouse_position
|
|
):
|
|
print(
|
|
"INFRA-ERROR: The new screen resolution or mouse positions are not what we expected"
|
|
)
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
|
|
class POINT(Structure):
|
|
_fields_ = [("x", c_ulong), ("y", c_ulong)]
|
|
|
|
|
|
def queryMousePosition():
|
|
pt = POINT()
|
|
windll.user32.GetCursorPos(byref(pt))
|
|
return {"x": pt.x, "y": pt.y}
|
|
|
|
|
|
def setCursorPos(x, y):
|
|
windll.user32.SetCursorPos(x, y)
|
|
|
|
|
|
def queryScreenResolution():
|
|
return {
|
|
"x": windll.user32.GetSystemMetrics(0),
|
|
"y": windll.user32.GetSystemMetrics(1),
|
|
}
|
|
|
|
|
|
def changeScreenResolution(xres=None, yres=None, BitsPerPixel=None):
|
|
import struct
|
|
|
|
DM_BITSPERPEL = 0x00040000
|
|
DM_PELSWIDTH = 0x00080000
|
|
DM_PELSHEIGHT = 0x00100000
|
|
CDS_FULLSCREEN = 0x00000004
|
|
SIZEOF_DEVMODE = 148
|
|
|
|
DevModeData = struct.calcsize("32BHH") * b"\x00"
|
|
DevModeData += struct.pack("H", SIZEOF_DEVMODE)
|
|
DevModeData += struct.calcsize("H") * b"\x00"
|
|
dwFields = (
|
|
(xres and DM_PELSWIDTH or 0)
|
|
| (yres and DM_PELSHEIGHT or 0)
|
|
| (BitsPerPixel and DM_BITSPERPEL or 0)
|
|
)
|
|
DevModeData += struct.pack("L", dwFields)
|
|
DevModeData += struct.calcsize("l9h32BHL") * b"\x00"
|
|
DevModeData += struct.pack("LLL", BitsPerPixel or 0, xres or 0, yres or 0)
|
|
DevModeData += struct.calcsize("8L") * b"\x00"
|
|
|
|
return windll.user32.ChangeDisplaySettingsA(DevModeData, 0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|