1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-24 03:16:49 +00:00

Changed settings storage to use the settings framework rather than rolling my own; this makes per-user settings work and fixes permission issues for non-admin users. Also made a small tweak to make the mouse work properly in high-dpi scenarios.

This commit is contained in:
JoshD 2016-07-18 17:28:10 -07:00
parent 5a17e7cfac
commit 5580a8a7a8
9 changed files with 384 additions and 146 deletions

View File

@ -1,6 +1,51 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Contralto.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
</configuration>
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
</appSettings>
<userSettings>
<Contralto.Properties.Settings>
<setting name="SystemType" serializeAs="String">
<value>2</value>
</setting>
<setting name="Drive0Image" serializeAs="String">
<value />
</setting>
<setting name="Drive1Image" serializeAs="String">
<value />
</setting>
<setting name="HostAddress" serializeAs="String">
<value>34</value>
</setting>
<setting name="HostPacketInterfaceName" serializeAs="String">
<value />
</setting>
<setting name="HostPacketInterfaceType" serializeAs="String">
<value>0</value>
</setting>
<setting name="AlternateBootType" serializeAs="String">
<value>0</value>
</setting>
<setting name="BootAddress" serializeAs="String">
<value>0</value>
</setting>
<setting name="BootFile" serializeAs="String">
<value>0</value>
</setting>
<setting name="InterlaceDisplay" serializeAs="String">
<value>False</value>
</setting>
<setting name="ThrottleSpeed" serializeAs="String">
<value>True</value>
</setting>
</Contralto.Properties.Settings>
</userSettings>
</configuration>

View File

@ -192,154 +192,46 @@ namespace Contralto
public static string GetRomPath(string romFileName)
{
return Path.Combine("ROM", romFileName);
}
}
/// <summary>
/// Reads the current configuration file from disk.
/// Reads the current configuration file from the app's configuration.
///
/// TODO: use reflection to do this.
/// </summary>
public static void ReadConfiguration()
{
try
{
using (StreamReader configStream = new StreamReader("contralto.cfg"))
{
//
// Config file consists of text lines containing name / value pairs:
// <Name> <Value>
// Whitespace is ignored
//
int lineNumber = 0;
while (!configStream.EndOfStream)
{
lineNumber++;
string line = configStream.ReadLine().Trim();
if (string.IsNullOrEmpty(line))
{
continue;
}
// Find whitespace separating tokens
int ws = line.IndexOfAny(new char[] { ' ', '\t' });
if (ws < 1)
{
Log.Write(LogType.Warning, LogComponent.Configuration, "Syntax error on line {0}. Ignoring.", lineNumber);
continue;
}
string parameter = line.Substring(0, ws);
string value = line.Substring(ws + 1, line.Length - ws - 1);
try
{
switch (parameter.ToLowerInvariant())
{
case "drive0image":
Drive0Image = value;
break;
case "drive1image":
Drive1Image = value;
break;
case "systemtype":
SystemType = (SystemType)Enum.Parse(typeof(SystemType), value, true);
break;
case "hostaddress":
HostAddress = Convert.ToByte(value, 8);
break;
case "hostpacketinterfacename":
HostPacketInterfaceName = value;
break;
case "hostpacketinterfacetype":
HostPacketInterfaceType = (PacketInterfaceType)Enum.Parse(typeof(PacketInterfaceType), value, true);
break;
case "alternateboottype":
AlternateBootType = (AlternateBootType)Enum.Parse(typeof(AlternateBootType), value, true);
break;
case "bootaddress":
BootAddress = Convert.ToUInt16(value, 8);
break;
case "bootfile":
BootFile = Convert.ToUInt16(value, 8);
break;
case "interlacedisplay":
InterlaceDisplay = bool.Parse(value);
break;
case "throttlespeed":
ThrottleSpeed = bool.Parse(value);
break;
default:
Log.Write(LogType.Warning, LogComponent.Configuration, "Invalid parameter on line {0}. Ignoring.", lineNumber);
break;
}
}
catch
{
Log.Write(LogType.Warning, LogComponent.Configuration, "Invalid value on line {0}. Ignoring.", lineNumber);
continue;
}
}
}
}
catch (Exception)
{
Log.Write(LogType.Warning, LogComponent.Configuration, "Configuration file 'contralto.cfg' could not be read; assuming default settings.");
WriteConfiguration();
}
Drive0Image = (string)Properties.Settings.Default["Drive0Image"];
Drive1Image = (string)Properties.Settings.Default["Drive1Image"];
SystemType = (SystemType)Properties.Settings.Default["SystemType"];
HostAddress = (byte)Properties.Settings.Default["HostAddress"];
HostPacketInterfaceName = (string)Properties.Settings.Default["HostPacketInterfaceName"];
HostPacketInterfaceType = (PacketInterfaceType)Properties.Settings.Default["HostPacketInterfaceType"];
AlternateBootType = (AlternateBootType)Properties.Settings.Default["AlternateBootType"];
BootAddress = (ushort)Properties.Settings.Default["BootAddress"];
BootFile = (ushort)Properties.Settings.Default["BootFile"];
InterlaceDisplay = (bool)Properties.Settings.Default["InterlaceDisplay"];
ThrottleSpeed = (bool)Properties.Settings.Default["ThrottleSpeed"];
}
/// <summary>
/// Commits the current configuration to disk.
/// Commits the current configuration to the app's settings.
/// </summary>
public static void WriteConfiguration()
{
try
{
using (StreamWriter configStream = new StreamWriter("contralto.cfg"))
{
if (!string.IsNullOrEmpty(Drive0Image))
{
configStream.WriteLine("Drive0Image {0}", Drive0Image);
}
Properties.Settings.Default["Drive0Image"] = Drive0Image;
Properties.Settings.Default["Drive1Image"] = Drive1Image;
Properties.Settings.Default["SystemType"] = (int)SystemType;
Properties.Settings.Default["HostAddress"] = HostAddress;
Properties.Settings.Default["HostPacketInterfaceName"] = HostPacketInterfaceName;
Properties.Settings.Default["HostPacketInterfaceType"] = (int)HostPacketInterfaceType;
Properties.Settings.Default["AlternateBootType"] = (int)AlternateBootType;
Properties.Settings.Default["BootAddress"] = BootAddress;
Properties.Settings.Default["BootFile"] = BootFile;
Properties.Settings.Default["InterlaceDisplay"] = InterlaceDisplay;
Properties.Settings.Default["ThrottleSpeed"] = ThrottleSpeed;
if (!string.IsNullOrEmpty(Drive1Image))
{
configStream.WriteLine("Drive1Image {0}", Drive1Image);
}
configStream.WriteLine("SystemType {0}", SystemType);
configStream.WriteLine("HostAddress {0}", Conversion.ToOctal(HostAddress));
if (!string.IsNullOrEmpty(HostPacketInterfaceName))
{
configStream.WriteLine("HostPacketInterfaceName {0}", HostPacketInterfaceName);
}
configStream.WriteLine("HostPacketInterfaceType {0}", HostPacketInterfaceType);
configStream.WriteLine("AlternateBootType {0}", AlternateBootType);
configStream.WriteLine("BootAddress {0}", Conversion.ToOctal(BootAddress));
configStream.WriteLine("BootFile {0}", Conversion.ToOctal(BootFile));
configStream.WriteLine("InterlaceDisplay {0}", InterlaceDisplay);
configStream.WriteLine("ThrottleSpeed {0}", ThrottleSpeed);
}
}
catch (Exception)
{
Log.Write(LogType.Warning, LogComponent.Configuration, "Configuration file 'contralto.cfg' could not be opened for writing.");
}
Properties.Settings.Default.Save();
}
}

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Contralto</RootNamespace>
<AssemblyName>Contralto</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
@ -26,6 +26,7 @@
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -89,6 +90,9 @@
<PropertyGroup>
<ApplicationIcon>Alto.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="PcapDotNet.Base, Version=1.0.2.21699, Culture=neutral, PublicKeyToken=4b6f3e583145a652, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -126,6 +130,11 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="UI\AboutBox.cs">
<SubType>Form</SubType>
</Compile>
@ -197,6 +206,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="app.manifest" />
<None Include="Disassembly\altocode24.mu" />
<None Include="App.config" />
<None Include="Disassembly\altoIIcode3.mu">
@ -259,6 +269,10 @@
<None Include="Disk\xmst76.dsk44">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="ROM\ACSOURCE.NEW">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Contralto")]
[assembly: AssemblyTitle("ContrAlto")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Vulcan Inc.")]
[assembly: AssemblyProduct("Contralto")]
[assembly: AssemblyCopyright("Copyright © Vulcan Inc. 2015")]
[assembly: AssemblyCompany("Living Computer Museum")]
[assembly: AssemblyProduct("ContrAlto")]
[assembly: AssemblyCopyright("Copyright © Living Computer Museum 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

170
Contralto/Properties/Settings.Designer.cs generated Normal file
View File

@ -0,0 +1,170 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Contralto.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("2")]
public int SystemType {
get {
return ((int)(this["SystemType"]));
}
set {
this["SystemType"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string Drive0Image {
get {
return ((string)(this["Drive0Image"]));
}
set {
this["Drive0Image"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string Drive1Image {
get {
return ((string)(this["Drive1Image"]));
}
set {
this["Drive1Image"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("34")]
public byte HostAddress {
get {
return ((byte)(this["HostAddress"]));
}
set {
this["HostAddress"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string HostPacketInterfaceName {
get {
return ((string)(this["HostPacketInterfaceName"]));
}
set {
this["HostPacketInterfaceName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
public int HostPacketInterfaceType {
get {
return ((int)(this["HostPacketInterfaceType"]));
}
set {
this["HostPacketInterfaceType"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
public int AlternateBootType {
get {
return ((int)(this["AlternateBootType"]));
}
set {
this["AlternateBootType"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
public ushort BootAddress {
get {
return ((ushort)(this["BootAddress"]));
}
set {
this["BootAddress"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
public ushort BootFile {
get {
return ((ushort)(this["BootFile"]));
}
set {
this["BootFile"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool InterlaceDisplay {
get {
return ((bool)(this["InterlaceDisplay"]));
}
set {
this["InterlaceDisplay"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool ThrottleSpeed {
get {
return ((bool)(this["ThrottleSpeed"]));
}
set {
this["ThrottleSpeed"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public string EnableWindowsFormsHighDpiAutoResizing {
get {
return ((string)(this["EnableWindowsFormsHighDpiAutoResizing"]));
}
set {
this["EnableWindowsFormsHighDpiAutoResizing"] = value;
}
}
}
}

View File

@ -0,0 +1,42 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Contralto.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="SystemType" Type="System.Int32" Scope="User">
<Value Profile="(Default)">2</Value>
</Setting>
<Setting Name="Drive0Image" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="Drive1Image" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="HostAddress" Type="System.Byte" Scope="User">
<Value Profile="(Default)">34</Value>
</Setting>
<Setting Name="HostPacketInterfaceName" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="HostPacketInterfaceType" Type="System.Int32" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="AlternateBootType" Type="System.Int32" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="BootAddress" Type="System.UInt16" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="BootFile" Type="System.UInt16" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="InterlaceDisplay" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="ThrottleSpeed" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="EnableWindowsFormsHighDpiAutoResizing" Type="System.String" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -645,7 +645,6 @@ namespace Contralto
return;
}
// We implement a crude "mouse capture" behavior by forcing the mouse cursor to the
// center of the display window and taking the delta of the last movement and using it
// to move the Alto's mouse.
@ -663,7 +662,7 @@ namespace Contralto
// Don't handle the very next Mouse Move event (which will just be the motion we caused in the
// below line...)
//_skipNextMouseMove = true;
_skipNextMouseMove = true;
Cursor.Position = DisplayBox.PointToScreen(middle);
}

View File

@ -230,8 +230,9 @@ namespace Contralto.UI
//
// First warn the user of changes that require a restart.
//
if (Configuration.HostPacketInterfaceName != iface.Description ||
Configuration.HostPacketInterfaceType != _selectedInterfaceType ||
if ((!(String.IsNullOrEmpty(Configuration.HostPacketInterfaceName) && EthernetInterfaceListBox.SelectedIndex == 0) &&
(Configuration.HostPacketInterfaceName != iface.Description ||
Configuration.HostPacketInterfaceType != _selectedInterfaceType)) ||
Configuration.SystemType != _selectedSystemType)
{
MessageBox.Show("Changes to CPU or host Ethernet configuration will not take effect until ContrAlto is restarted.");

75
Contralto/app.manifest Normal file
View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. -->
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>