A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using System.Collections.Generic;
6using System.Diagnostics;
7using System.IO;
8using System.Linq;
9using osu.Framework.Extensions.IEnumerableExtensions;
10using osu.Framework.Input;
11using osu.Framework.Input.Bindings;
12using osu.Framework.Input.Handlers;
13using osu.Framework.Input.Handlers.Mouse;
14using osu.Framework.Platform.Windows.Native;
15
16namespace osu.Framework.Platform.Windows
17{
18 public class WindowsGameHost : DesktopGameHost
19 {
20 private TimePeriod timePeriod;
21
22 public override Clipboard GetClipboard() => new WindowsClipboard();
23
24 public override IEnumerable<string> UserStoragePaths =>
25 // on windows this is guaranteed to exist (and be usable) so don't fallback to the base/default.
26 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).Yield();
27
28#if NET5_0
29 [System.Runtime.Versioning.SupportedOSPlatform("windows")]
30#endif
31 public override bool CapsLockEnabled => Console.CapsLock;
32
33 internal WindowsGameHost(string gameName, bool bindIPC = false, bool portableInstallation = false)
34 : base(gameName, bindIPC, portableInstallation)
35 {
36 }
37
38 public override void OpenFileExternally(string filename)
39 {
40 if (Directory.Exists(filename))
41 {
42 Process.Start("explorer.exe", filename);
43 return;
44 }
45
46 base.OpenFileExternally(filename);
47 }
48
49 protected override IEnumerable<InputHandler> CreateAvailableInputHandlers()
50 {
51 // for windows platforms we want to override the relative mouse event handling behaviour.
52 return base.CreateAvailableInputHandlers()
53 .Where(t => !(t is MouseHandler))
54 .Concat(new InputHandler[] { new WindowsMouseHandler() });
55 }
56
57 protected override void SetupForRun()
58 {
59 base.SetupForRun();
60
61 // OnActivate / OnDeactivate may not fire, so the initial activity state may be unknown here.
62 // In order to be certain we have the correct activity state we are querying the Windows API here.
63
64 timePeriod = new TimePeriod(1);
65 }
66
67 protected override IWindow CreateWindow() => new WindowsWindow();
68
69 public override IEnumerable<KeyBinding> PlatformKeyBindings => base.PlatformKeyBindings.Concat(new[]
70 {
71 new KeyBinding(new KeyCombination(InputKey.Alt, InputKey.F4), PlatformAction.Exit)
72 }).ToList();
73
74 protected override void Dispose(bool isDisposing)
75 {
76 timePeriod?.Dispose();
77 base.Dispose(isDisposing);
78 }
79
80 protected override void OnActivated()
81 {
82 Execution.SetThreadExecutionState(Execution.ExecutionState.Continuous | Execution.ExecutionState.SystemRequired | Execution.ExecutionState.DisplayRequired);
83 base.OnActivated();
84 }
85
86 protected override void OnDeactivated()
87 {
88 Execution.SetThreadExecutionState(Execution.ExecutionState.Continuous);
89 base.OnDeactivated();
90 }
91 }
92}