1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-29 07:04:35 +01:00

Doc: Improve documentation for .mm files. (#15009)

This commit is contained in:
Cyprian Klimaszewski
2026-01-10 17:13:46 +01:00
committed by GitHub
parent 14e0917ae4
commit 666073fc7b
7 changed files with 362 additions and 172 deletions

View File

@@ -45,7 +45,7 @@ PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 2 TAB_SIZE = 2
ALIASES = ALIASES = important="@attention" # @important is available in newer versions of doxygen.
OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_FOR_FORTRAN = NO
@@ -134,7 +134,9 @@ FILE_PATTERNS = *.c \
*.cpp \ *.cpp \
*.c++ \ *.c++ \
*.h \ *.h \
*.hpp *.hpp \
*.mm \
*.m
RECURSIVE = YES RECURSIVE = YES
EXCLUDE = EXCLUDE =
EXCLUDE_SYMLINKS = NO EXCLUDE_SYMLINKS = NO
@@ -317,6 +319,7 @@ PREDEFINED = WITH_ZLIB \
WITH_HARFBUZZ \ WITH_HARFBUZZ \
WITH_ICU_I18N \ WITH_ICU_I18N \
UNICODE \ UNICODE \
DOXYGEN_API \
_UNICODE \ _UNICODE \
_GNU_SOURCE \ _GNU_SOURCE \
FINAL= FINAL=

View File

@@ -4,6 +4,7 @@ add_files(
font_osx.h font_osx.h
macos.h macos.h
macos.mm macos.mm
macos_objective_c.h
osx_stdafx.h osx_stdafx.h
string_osx.cpp string_osx.cpp
string_osx.h string_osx.h

View File

@@ -5,7 +5,12 @@
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>. * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
*/ */
/** @file macos.mm Code related to MacOSX. */ /**
* @file macos.mm Code related to MacOSX.
*
* This file contains objective C.
* Apple uses objective C instead of plain C to interact with OS specific/native functions.
*/
#include "../../stdafx.h" #include "../../stdafx.h"
#include "../../core/bitmath_func.hpp" #include "../../core/bitmath_func.hpp"
@@ -14,18 +19,7 @@
#include "../../string_func.h" #include "../../string_func.h"
#include "../../fileio_func.h" #include "../../fileio_func.h"
#include <pthread.h> #include <pthread.h>
#include "macos_objective_c.h"
#define Rect OTTDRect
#define Point OTTDPoint
#include <AppKit/AppKit.h>
#undef Rect
#undef Point
/*
* This file contains objective C
* Apple uses objective C instead of plain C to interact with OS specific/native functions
*/
#ifdef WITH_COCOA #ifdef WITH_COCOA
static NSAutoreleasePool *_ottd_autorelease_pool; static NSAutoreleasePool *_ottd_autorelease_pool;
@@ -58,44 +52,28 @@ void GetMacOSVersion(int *return_major, int *return_minor, int *return_bugfix)
} }
#ifdef WITH_COCOA #ifdef WITH_COCOA
extern void CocoaDialog(std::string_view title, std::string_view message, std::string_view buttonLabel); extern void CocoaDialog(std::string_view title, std::string_view message, std::string_view buttonLabel);
/**
* Show the system dialogue message (Cocoa on MacOSX).
*
* @param title Window title.
* @param message Message text.
* @param buttonLabel Button text.
*/
void ShowMacDialog(std::string_view title, std::string_view message, std::string_view buttonLabel)
{
CocoaDialog(title, message, buttonLabel);
}
#else
/**
* Show the system dialogue message (console on MacOSX).
*
* @param title Window title.
* @param message Message text.
* @param buttonLabel Button text.
*/
void ShowMacDialog(std::string_view title, std::string_view message, std::string_view buttonLabel)
{
fmt::print(stderr, "{}: {}\n", title, message);
}
#endif #endif
/**
* Show the system dialogue message, uses Cocoa if available and console otherwise.
* @param title Window title.
* @param message Message text.
* @param buttonLabel Button text.
*/
void ShowMacDialog(std::string_view title, std::string_view message, std::string_view buttonLabel)
{
#ifdef WITH_COCOA
CocoaDialog(title, message, buttonLabel);
#else
fmt::print(stderr, "{}: {}\n", title, message);
#endif
}
/** /**
* Show an error message. * Show an error message.
* * @param buf Text with error message.
* @param buf error message text. * @param system Whether message text originates from OS.
* @param system message text originates from OS.
*/ */
void ShowOSErrorBox(std::string_view buf, bool system) void ShowOSErrorBox(std::string_view buf, bool system)
{ {
@@ -107,13 +85,18 @@ void ShowOSErrorBox(std::string_view buf, bool system)
} }
} }
/**
* Opens browser on MacOS.
* @param url Web page address to open.
*/
void OSOpenBrowser(const std::string &url) void OSOpenBrowser(const std::string &url)
{ {
[ [ NSWorkspace sharedWorkspace ] openURL:[ NSURL URLWithString:[ NSString stringWithUTF8String:url.c_str() ] ] ]; [ [ NSWorkspace sharedWorkspace ] openURL:[ NSURL URLWithString:[ NSString stringWithUTF8String:url.c_str() ] ] ];
} }
/** /**
* Determine and return the current user's locale. * Determine and return the current user's charset.
* @return String containing current charset, or std::nullopt if not-determinable.
*/ */
std::optional<std::string> GetCurrentLocale(const char *) std::optional<std::string> GetCurrentLocale(const char *)
{ {
@@ -220,6 +203,10 @@ void MacOSSetThreadName(const std::string &name)
} }
} }
/**
* Ask OS how much RAM it has physically attached.
* @return Number of available bytes.
*/
uint64_t MacOSGetPhysicalMemory() uint64_t MacOSGetPhysicalMemory()
{ {
return [ [ NSProcessInfo processInfo ] physicalMemory ]; return [ [ NSProcessInfo processInfo ] physicalMemory ];

View File

@@ -0,0 +1,28 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
*/
/** @file macos_objective_c.h Includes of mac os specific headers wich contain objective c. */
#ifndef MACOS_OBJECTIVE_C_H
#define MACOS_OBJECTIVE_C_H
/** Macro that prevents name conflicts between included headers. */
#define Rect OTTDRect
/** Macro that prevents name conflicts between included headers. */
#define Point OTTDPoint
#include <AppKit/AppKit.h>
#ifdef WITH_COCOA
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#endif /* WITH_COCOA */
#undef Rect
#undef Point
#endif /* MACOS_OBJECTIVE_C_H */

View File

@@ -5,22 +5,25 @@
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>. * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
*/ */
/** @file cocoa_ogl.mm Code related to the cocoa OpengL video driver. */ /**
* @file cocoa_ogl.mm Code related to the cocoa OpengL video driver.
*
* @important Notice regarding all modifications!!!!!!!
* There are certain limitations because the file is objective C++.
* gdb has limitations.
* C++ and objective C code can't be joined in all cases (classes stuff).
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
*/
#ifdef WITH_COCOA #if defined(WITH_COCOA) || defined(DOXYGEN_API)
#include "../../stdafx.h" #include "../../stdafx.h"
#include "../../os/macosx/macos.h" #include "../../os/macosx/macos.h"
/** Macro defined before OpenGL and GLUT includes to avoid deprecation messages. */
#define GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION
#define Rect OTTDRect #include "../../os/macosx/macos_objective_c.h"
#define Point OTTDPoint
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#undef Rect
#undef Point
#include "../../openttd.h" #include "../../openttd.h"
#include "../../debug.h" #include "../../debug.h"
#include "../../core/geometry_func.hpp" #include "../../core/geometry_func.hpp"
@@ -38,15 +41,6 @@
static Palette _local_palette; ///< Current palette to use for drawing. static Palette _local_palette; ///< Current palette to use for drawing.
/**
* Important notice regarding all modifications!!!!!!!
* There are certain limitations because the file is objective C++.
* gdb has limitations.
* C++ and objective C code can't be joined in all cases (classes stuff).
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
*/
/** Platform-specific callback to get an OpenGL function pointer. */ /** Platform-specific callback to get an OpenGL function pointer. */
static OGLProc GetOGLProcAddressCallback(const char *proc) static OGLProc GetOGLProcAddressCallback(const char *proc)
{ {
@@ -181,6 +175,7 @@ static bool _allowSoftware;
@end @end
/** Storage for instance of the FVideoDriver_CocoaOpenGL class. */
static FVideoDriver_CocoaOpenGL iFVideoDriver_CocoaOpenGL; static FVideoDriver_CocoaOpenGL iFVideoDriver_CocoaOpenGL;
@@ -330,4 +325,4 @@ void VideoDriver_CocoaOpenGL::Paint()
[ CATransaction commit ]; [ CATransaction commit ];
} }
#endif /* WITH_COCOA */ #endif /* WITH_COCOA or DOXYGEN_API */

View File

@@ -5,26 +5,22 @@
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>. * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
*/ */
/** @file cocoa_v.mm Code related to the cocoa video driver(s). */ /**
* @file cocoa_v.mm Code related to the cocoa video driver(s).
*
* @important Notice regarding all modifications!!!!!!!
* There are certain limitations because the file is objective C++.
* gdb has limitations.
* C++ and objective C code can't be joined in all cases (classes stuff).
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
*/
/****************************************************************************** #if defined(WITH_COCOA) || defined(DOXYGEN_API)
* Cocoa video driver *
* Known things left to do: *
* Nothing at the moment. *
******************************************************************************/
#ifdef WITH_COCOA
#include "../../stdafx.h" #include "../../stdafx.h"
#include "../../os/macosx/macos.h" #include "../../os/macosx/macos.h"
#define Rect OTTDRect #include "../../os/macosx/macos_objective_c.h"
#define Point OTTDPoint
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#undef Rect
#undef Point
#include "../../openttd.h" #include "../../openttd.h"
#include "../../debug.h" #include "../../debug.h"
#include "../../error_func.h" #include "../../error_func.h"
@@ -45,18 +41,9 @@
#import <sys/param.h> /* for MAXPATHLEN */ #import <sys/param.h> /* for MAXPATHLEN */
#import <sys/time.h> /* gettimeofday */ #import <sys/time.h> /* gettimeofday */
/** bool _cocoa_video_started = false; ///< Is the Cocoa video driver running.
* Important notice regarding all modifications!!!!!!!
* There are certain limitations because the file is objective C++.
* gdb has limitations.
* C++ and objective C code can't be joined in all cases (classes stuff).
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
*/
bool _cocoa_video_started = false;
static Palette _local_palette; ///< Current palette to use for drawing. static Palette _local_palette; ///< Current palette to use for drawing.
extern bool _tab_is_down; ///< Is tab button pressed.
extern bool _tab_is_down;
/** List of common display/window sizes. */ /** List of common display/window sizes. */
@@ -110,7 +97,10 @@ void VideoDriver_Cocoa::Stop()
_cocoa_video_started = false; _cocoa_video_started = false;
} }
/** Common driver initialization. */ /**
* Common driver initialization.
* @return Error message if one has occurred, std::nullopt otherwise.
*/
std::optional<std::string_view> VideoDriver_Cocoa::Initialize() std::optional<std::string_view> VideoDriver_Cocoa::Initialize()
{ {
if (!MacOSVersionIsAtLeast(10, 7, 0)) return "The Cocoa video driver requires Mac OS X 10.7 or later."; if (!MacOSVersionIsAtLeast(10, 7, 0)) return "The Cocoa video driver requires Mac OS X 10.7 or later.";
@@ -241,6 +231,7 @@ void VideoDriver_Cocoa::EditBoxLostFocus()
/** /**
* Get refresh rates of all connected monitors. * Get refresh rates of all connected monitors.
* @return Refresh rates of all connected monitors.
*/ */
std::vector<int> VideoDriver_Cocoa::GetListOfMonitorRefreshRates() std::vector<int> VideoDriver_Cocoa::GetListOfMonitorRefreshRates()
{ {
@@ -265,6 +256,7 @@ std::vector<int> VideoDriver_Cocoa::GetListOfMonitorRefreshRates()
/** /**
* Get the resolution of the main screen. * Get the resolution of the main screen.
* @return The resolution of the main screen.
*/ */
Dimension VideoDriver_Cocoa::GetScreenSize() const Dimension VideoDriver_Cocoa::GetScreenSize() const
{ {
@@ -272,7 +264,10 @@ Dimension VideoDriver_Cocoa::GetScreenSize() const
return { static_cast<uint>(NSWidth(frame)), static_cast<uint>(NSHeight(frame)) }; return { static_cast<uint>(NSWidth(frame)), static_cast<uint>(NSHeight(frame)) };
} }
/** Lock video buffer for drawing if it isn't already mapped. */ /**
* Lock video buffer for drawing if it isn't already mapped.
* @return True on success and false otherwise.
*/
bool VideoDriver_Cocoa::LockVideoBuffer() bool VideoDriver_Cocoa::LockVideoBuffer()
{ {
if (this->buffer_locked) return false; if (this->buffer_locked) return false;
@@ -351,6 +346,7 @@ void VideoDriver_Cocoa::UpdateVideoModes()
* Build window and view with a given size. * Build window and view with a given size.
* @param width Window width. * @param width Window width.
* @param height Window height. * @param height Window height.
* @return True on success and false otherwise.
*/ */
bool VideoDriver_Cocoa::MakeWindow(int width, int height) bool VideoDriver_Cocoa::MakeWindow(int width, int height)
{ {
@@ -480,15 +476,21 @@ void VideoDriver_Cocoa::MainLoopReal()
} }
/* Subclass of OTTD_CocoaView to fix Quartz rendering */ /** Subclass of OTTD_CocoaView to fix Quartz rendering */
@interface OTTD_QuartzView : NSView { @interface OTTD_QuartzView : NSView {
VideoDriver_CocoaQuartz *driver; VideoDriver_CocoaQuartz *driver; ///< The driver to fix rendering for.
} }
- (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_CocoaQuartz *)drv; - (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_CocoaQuartz *)drv;
@end @end
@implementation OTTD_QuartzView @implementation OTTD_QuartzView
/**
* Construct new instance.
* @param frameRect Size of frame.
* @param drv Driver to fix rendering for.
* @return The newly created instance.
*/
- (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_CocoaQuartz *)drv - (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_CocoaQuartz *)drv
{ {
if (self = [ super initWithFrame:frameRect ]) { if (self = [ super initWithFrame:frameRect ]) {
@@ -504,21 +506,34 @@ void VideoDriver_Cocoa::MainLoopReal()
return self; return self;
} }
/**
* Specifies whether the view accepts first responder.
* @return Always no.
*/
- (BOOL)acceptsFirstResponder - (BOOL)acceptsFirstResponder
{ {
return NO; return NO;
} }
/**
* Specifies whether the view is opaque.
* @return Always yes.
*/
- (BOOL)isOpaque - (BOOL)isOpaque
{ {
return YES; return YES;
} }
/**
* Specifies whether the view wants updates for layer.
* @return Always yes.
*/
- (BOOL)wantsUpdateLayer - (BOOL)wantsUpdateLayer
{ {
return YES; return YES;
} }
/** Updates the layer based on driver data. */
- (void)updateLayer - (void)updateLayer
{ {
if (driver->cgcontext == nullptr) return; if (driver->cgcontext == nullptr) return;
@@ -529,6 +544,7 @@ void VideoDriver_Cocoa::MainLoopReal()
CGImageRelease(fullImage); CGImageRelease(fullImage);
} }
/** Updates members with new values after changes in driver. */
- (void)viewDidChangeBackingProperties - (void)viewDidChangeBackingProperties
{ {
[ super viewDidChangeBackingProperties ]; [ super viewDidChangeBackingProperties ];
@@ -538,10 +554,12 @@ void VideoDriver_Cocoa::MainLoopReal()
@end @end
/**
static FVideoDriver_CocoaQuartz iFVideoDriver_CocoaQuartz; * Clear buffer to opaque black.
* @param buffer Pointer to the buffer.
/** Clear buffer to opaque black. */ * @param pitch Width of the buffer.
* @param height Height of the buffer.
*/
static void ClearWindowBuffer(uint32_t *buffer, uint32_t pitch, uint32_t height) static void ClearWindowBuffer(uint32_t *buffer, uint32_t pitch, uint32_t height)
{ {
uint32_t fill = Colour(0, 0, 0).data; uint32_t fill = Colour(0, 0, 0).data;
@@ -609,8 +627,11 @@ NSView *VideoDriver_CocoaQuartz::AllocateDrawView()
return [ [ OTTD_QuartzView alloc ] initWithFrame:[ this->cocoaview bounds ] andDriver:this ]; return [ [ OTTD_QuartzView alloc ] initWithFrame:[ this->cocoaview bounds ] andDriver:this ];
} }
/** Resize the window. */ /**
void VideoDriver_CocoaQuartz::AllocateBackingStore(bool) * Resize the window.
* @param force If true window resizing will be forced.
*/
void VideoDriver_CocoaQuartz::AllocateBackingStore([[maybe_unused]] bool force)
{ {
if (this->window == nil || this->cocoaview == nil || this->setup) return; if (this->window == nil || this->cocoaview == nil || this->setup) return;
@@ -684,7 +705,11 @@ void VideoDriver_CocoaQuartz::BlitIndexedToView32(int left, int top, int right,
} }
} }
/** Update the palette */ /**
* Update the palette
* @param first_colour Index of first colour to update.
* @param num_colours How many colours to update, should be greater than 0.
*/
void VideoDriver_CocoaQuartz::UpdatePalette(uint first_colour, uint num_colours) void VideoDriver_CocoaQuartz::UpdatePalette(uint first_colour, uint num_colours)
{ {
if (this->buffer_depth != 8) return; if (this->buffer_depth != 8) return;
@@ -756,4 +781,4 @@ void VideoDriver_CocoaQuartz::Paint()
this->dirty_rect = {}; this->dirty_rect = {};
} }
#endif /* WITH_COCOA */ #endif /* WITH_COCOA or DOXYGEN_API */

View File

@@ -5,25 +5,24 @@
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>. * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
*/ */
/** @file cocoa_wnd.mm Code related to OS interface for the cocoa video driver. */ /**
* @file cocoa_wnd.mm Code related to OS interface for the cocoa video driver.
*
* @important Notice regarding all modifications!!!!!!!
* There are certain limitations because the file is objective C++.
* gdb has limitations.
* C++ and objective C code can't be joined in all cases (classes stuff).
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
*
* @todo List available resolutions.
*/
/****************************************************************************** #if defined(WITH_COCOA) || defined(DOXYGEN_API)
* Cocoa video driver *
* Known things left to do: *
* List available resolutions. *
******************************************************************************/
#ifdef WITH_COCOA
#include "../../stdafx.h" #include "../../stdafx.h"
#include "../../os/macosx/macos.h" #include "../../os/macosx/macos.h"
#define Rect OTTDRect #include "../../os/macosx/macos_objective_c.h"
#define Point OTTDPoint
#import <Cocoa/Cocoa.h>
#undef Rect
#undef Point
#include "../../openttd.h" #include "../../openttd.h"
#include "../../debug.h" #include "../../debug.h"
#include "cocoa_v.h" #include "cocoa_v.h"
@@ -43,22 +42,18 @@
/* Table data for key mapping. */ /* Table data for key mapping. */
#include "cocoa_keys.h" #include "cocoa_keys.h"
/** /** Structure to store information about single touch bar button. */
* Important notice regarding all modifications!!!!!!!
* There are certain limitations because the file is objective C++.
* gdb has limitations.
* C++ and objective C code can't be joined in all cases (classes stuff).
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
*/
struct TouchBarButton { struct TouchBarButton {
NSTouchBarItemIdentifier key; NSTouchBarItemIdentifier key; ///< Unique identifier for this button.
SpriteID sprite; SpriteID sprite; ///< Sprite to display on button.
MainToolbarHotkeys hotkey; MainToolbarHotkeys hotkey; ///< Index of widget that corresponds to this button.
NSString *fallback_text; NSString *fallback_text; ///< Text to use if sprite is unavailable.
}; };
/* 9 items can be displayed on the touch bar when using default buttons. */ /**
* Storage of defined touch bar buttons.
* @note 9 items can be displayed on the touch bar when using default buttons.
*/
static const std::array<TouchBarButton, 9> _touchbar_buttons{{ static const std::array<TouchBarButton, 9> _touchbar_buttons{{
{ @"openttd.pause", SPR_IMG_PAUSE, MTHK_PAUSE, @"Pause" }, { @"openttd.pause", SPR_IMG_PAUSE, MTHK_PAUSE, @"Pause" },
{ @"openttd.fastforward", SPR_IMG_FASTFORWARD, MTHK_FASTFORWARD, @"Fast Forward" }, { @"openttd.fastforward", SPR_IMG_FASTFORWARD, MTHK_FASTFORWARD, @"Fast Forward" },
@@ -71,23 +66,23 @@ static const std::array<TouchBarButton, 9> _touchbar_buttons{{
{ @"openttd.build_airport", SPR_IMG_BUILDAIR, MTHK_BUILD_AIRPORT, @"Airport" } { @"openttd.build_airport", SPR_IMG_BUILDAIR, MTHK_BUILD_AIRPORT, @"Airport" }
}}; }};
bool _allow_hidpi_window = true; // Referenced from table/misc_settings.ini bool _allow_hidpi_window = true; ///< Storage for allow_hidpi setting. If true renders OTTD in native resolution. @see table/misc_settings.ini
@interface OTTDMain : NSObject <NSApplicationDelegate> @interface OTTDMain : NSObject <NSApplicationDelegate>
@end @end
/** Name of notification observer used to restart the game loop if necessary. */
NSString *OTTDMainLaunchGameEngine = @"ottdmain_launch_game_engine"; NSString *OTTDMainLaunchGameEngine = @"ottdmain_launch_game_engine";
bool _tab_is_down; bool _tab_is_down; ///< Is tab button pressed.
static bool _cocoa_video_dialog = false; static bool _cocoa_video_dialog = false; ///< True iff inside the scope of CocoaDialog method.
static OTTDMain *_ottd_main; static OTTDMain *_ottd_main; ///< App delegate instance of OTTDMain.
/** /**
* Count the number of UTF-16 code points in a range of an UTF-8 string. * Count the number of UTF-16 code points in a range of an UTF-8 string.
* @param from Start of the range. * @param str The view in range of the string.
* @param to End of the range.
* @return Number of UTF-16 code points in the range. * @return Number of UTF-16 code points in the range.
*/ */
static NSUInteger CountUtf16Units(std::string_view str) static NSUInteger CountUtf16Units(std::string_view str)
@@ -141,6 +136,10 @@ static std::vector<char32_t> NSStringToUTF32(NSString *s)
return unicode_str; return unicode_str;
} }
/**
* Free memory where data was stored.
* @param data Pointer to memory that will be freed.
*/
static void CGDataFreeCallback(void *, const void *data, size_t) static void CGDataFreeCallback(void *, const void *data, size_t)
{ {
delete[] (const uint32_t *)data; delete[] (const uint32_t *)data;
@@ -326,6 +325,7 @@ static void setupWindowMenu()
/** /**
* Startup the application. * Startup the application.
* @return True iff startup was successful.
*/ */
bool CocoaSetupApplication() bool CocoaSetupApplication()
{ {
@@ -376,7 +376,7 @@ void CocoaExitApplication()
* @param message Message text. * @param message Message text.
* @param buttonLabel Button text. * @param buttonLabel Button text.
* *
* @note This is needed since sometimes assert is called before the videodriver is initialized . * @note This is needed since sometimes assert is called before the videodriver is initialized.
*/ */
void CocoaDialog(std::string_view title, std::string_view message, std::string_view buttonLabel) void CocoaDialog(std::string_view title, std::string_view message, std::string_view buttonLabel)
{ {
@@ -410,6 +410,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
* Re-implement the system cursor in order to allow hiding and showing it nicely * Re-implement the system cursor in order to allow hiding and showing it nicely
*/ */
@implementation NSCursor (OTTD_CocoaCursor) @implementation NSCursor (OTTD_CocoaCursor)
/**
* Create clear cursor for cocoa driver.
* @return The created cursor.
*/
+ (NSCursor *) clearCocoaCursor + (NSCursor *) clearCocoaCursor
{ {
/* RAW 16x16 transparent GIF */ /* RAW 16x16 transparent GIF */
@@ -427,7 +431,7 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
@implementation OTTD_CocoaWindow { @implementation OTTD_CocoaWindow {
VideoDriver_Cocoa *driver; VideoDriver_Cocoa *driver;
bool touchbar_created; bool touchbar_created; ///< Whether the touchbar exists.
} }
/** /**
@@ -536,8 +540,8 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
@implementation OTTD_CocoaView { @implementation OTTD_CocoaView {
float _current_magnification; float _current_magnification;
NSUInteger _current_mods; NSUInteger _current_mods; ///< Currently applied modifier flags.
bool _emulated_down; bool _emulated_down; ///< Whether the mouse button is emulated or real.
bool _use_hidpi; ///< Render content in native resolution? bool _use_hidpi; ///< Render content in native resolution?
} }
@@ -602,14 +606,16 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
[ track release ]; [ track release ];
} }
/** /**
* Make OpenTTD aware that it has control over the mouse * Make OpenTTD aware that it has control over the mouse.
* @param theEvent Information about occurred event.
*/ */
- (void)mouseEntered:(NSEvent *)theEvent - (void)mouseEntered:(NSEvent *)theEvent
{ {
_cursor.in_window = true; _cursor.in_window = true;
} }
/** /**
* Make OpenTTD aware that it has NOT control over the mouse * Make OpenTTD aware that it has NO control over the mouse.
* @param theEvent Information about occurred event.
*/ */
- (void)mouseExited:(NSEvent *)theEvent - (void)mouseExited:(NSEvent *)theEvent
{ {
@@ -618,9 +624,9 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
} }
/** /**
* Return the mouse location * Return the mouse location.
* @param event UI event * @param e Information about occurred event.
* @return mouse location as NSPoint * @return Mouse location as NSPoint.
*/ */
- (NSPoint)mousePositionFromEvent:(NSEvent *)e - (NSPoint)mousePositionFromEvent:(NSEvent *)e
{ {
@@ -631,6 +637,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
return [ self getRealRect:NSMakeRect(pt.x, self.bounds.size.height - pt.y, 0, 0) ].origin; return [ self getRealRect:NSMakeRect(pt.x, self.bounds.size.height - pt.y, 0, 0) ].origin;
} }
/**
* Internal handler of mouse movement.
* @param event Information about occurred event.
*/
- (void)internalMouseMoveEvent:(NSEvent *)event - (void)internalMouseMoveEvent:(NSEvent *)event
{ {
if (_cursor.fix_at) { if (_cursor.fix_at) {
@@ -643,6 +653,9 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
HandleMouseEvents(); HandleMouseEvents();
} }
/**
* Internal handler of mouse buttons.
*/
- (void)internalMouseButtonEvent - (void)internalMouseButtonEvent
{ {
bool cur_fix = _cursor.fix_at; bool cur_fix = _cursor.fix_at;
@@ -652,6 +665,11 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
if (cur_fix != _cursor.fix_at) CGAssociateMouseAndMouseCursorPosition(!_cursor.fix_at); if (cur_fix != _cursor.fix_at) CGAssociateMouseAndMouseCursorPosition(!_cursor.fix_at);
} }
/**
* Check if right mouse button should be emulated when left button is pressed.
* @param event Information about occurred event.
* @return True iff right button should be emulated instead of left one.
*/
- (BOOL)emulateRightButton:(NSEvent *)event - (BOOL)emulateRightButton:(NSEvent *)event
{ {
uint32_t keymask = 0; uint32_t keymask = 0;
@@ -661,15 +679,28 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
return (event.modifierFlags & keymask) != 0; return (event.modifierFlags & keymask) != 0;
} }
/**
* Handler of mouse movement.
* @param event Information about occurred event.
*/
- (void)mouseMoved:(NSEvent *)event - (void)mouseMoved:(NSEvent *)event
{ {
[ self internalMouseMoveEvent:event ]; [ self internalMouseMoveEvent:event ];
} }
/**
* Handler of mouse movement while left button is down.
* @param event Information about occurred event.
*/
- (void)mouseDragged:(NSEvent *)event - (void)mouseDragged:(NSEvent *)event
{ {
[ self internalMouseMoveEvent:event ]; [ self internalMouseMoveEvent:event ];
} }
/**
* Handler of left mouse button pressing.
* @param event Information about occurred event.
*/
- (void)mouseDown:(NSEvent *)event - (void)mouseDown:(NSEvent *)event
{ {
if ([ self emulateRightButton:event ]) { if ([ self emulateRightButton:event ]) {
@@ -680,6 +711,11 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
[ self internalMouseButtonEvent ]; [ self internalMouseButtonEvent ];
} }
} }
/**
* Handler of left mouse button releasing.
* @param event Information about occurred event.
*/
- (void)mouseUp:(NSEvent *)event - (void)mouseUp:(NSEvent *)event
{ {
if (self->_emulated_down) { if (self->_emulated_down) {
@@ -692,22 +728,40 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
} }
} }
/**
* Handler of mouse movement when right button is down.
* @param event Information about occurred event.
*/
- (void)rightMouseDragged:(NSEvent *)event - (void)rightMouseDragged:(NSEvent *)event
{ {
[ self internalMouseMoveEvent:event ]; [ self internalMouseMoveEvent:event ];
} }
/**
* Handler of right mouse button pressing.
* @param event Information about occurred event.
*/
- (void)rightMouseDown:(NSEvent *)event - (void)rightMouseDown:(NSEvent *)event
{ {
_right_button_down = true; _right_button_down = true;
_right_button_clicked = true; _right_button_clicked = true;
[ self internalMouseButtonEvent ]; [ self internalMouseButtonEvent ];
} }
/**
* Handler of right mouse button releasing.
* @param event Information about occurred event.
*/
- (void)rightMouseUp:(NSEvent *)event - (void)rightMouseUp:(NSEvent *)event
{ {
_right_button_down = false; _right_button_down = false;
[ self internalMouseButtonEvent ]; [ self internalMouseButtonEvent ];
} }
/**
* Handler of mouse wheel scrolling.
* @param event Information about occurred event.
*/
- (void)scrollWheel:(NSEvent *)event - (void)scrollWheel:(NSEvent *)event
{ {
if ([ event deltaY ] > 0.0) { /* Scroll up */ if ([ event deltaY ] > 0.0) { /* Scroll up */
@@ -737,6 +791,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
_cursor.wheel_moved = true; _cursor.wheel_moved = true;
} }
/**
* Handler of magnification events.
* @param event Information about occurred event.
*/
- (void)magnifyWithEvent:(NSEvent *)event - (void)magnifyWithEvent:(NSEvent *)event
{ {
/* Pinch open or close gesture. */ /* Pinch open or close gesture. */
@@ -754,6 +812,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
} }
} }
/**
* Handler of gesture to end magnification.
* @param event Information about occurred event.
*/
- (void)endGestureWithEvent:(NSEvent *)event - (void)endGestureWithEvent:(NSEvent *)event
{ {
/* Gesture ended. */ /* Gesture ended. */
@@ -761,6 +823,11 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
} }
/**
* Internal handler of keyboard keys.
* @param event Information about occurred event.
* @return Whether event should be interpreted.
*/
- (BOOL)internalHandleKeycode:(unsigned short)keycode unicode:(char32_t)unicode pressed:(BOOL)down modifiers:(NSUInteger)modifiers - (BOOL)internalHandleKeycode:(unsigned short)keycode unicode:(char32_t)unicode pressed:(BOOL)down modifiers:(NSUInteger)modifiers
{ {
switch (keycode) { switch (keycode) {
@@ -833,6 +900,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
return interpret_keys; return interpret_keys;
} }
/**
* Handler of keyboard key pressing.
* @param event Information about occurred event.
*/
- (void)keyDown:(NSEvent *)event - (void)keyDown:(NSEvent *)event
{ {
/* Quit, hide and minimize */ /* Quit, hide and minimize */
@@ -862,6 +933,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
} }
} }
/**
* Handler of keyboard key releasing.
* @param event Information about occurred event.
*/
- (void)keyUp:(NSEvent *)event - (void)keyUp:(NSEvent *)event
{ {
/* Quit, hide and minimize */ /* Quit, hide and minimize */
@@ -882,6 +957,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
[ self internalHandleKeycode:event.keyCode unicode:unicode_str[0] pressed:NO modifiers:event.modifierFlags ]; [ self internalHandleKeycode:event.keyCode unicode:unicode_str[0] pressed:NO modifiers:event.modifierFlags ];
} }
/**
* Handler of modifiers.
* @param event Information about occurred event.
*/
- (void)flagsChanged:(NSEvent *)event - (void)flagsChanged:(NSEvent *)event
{ {
const int mapping[] = { QZ_CAPSLOCK, QZ_LSHIFT, QZ_LCTRL, QZ_LALT, QZ_LMETA }; const int mapping[] = { QZ_CAPSLOCK, QZ_LSHIFT, QZ_LCTRL, QZ_LALT, QZ_LMETA };
@@ -1082,141 +1161,210 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
return [ NSArray array ]; return [ NSArray array ];
} }
/** Delete single character left of the cursor. */ /**
* Delete single character left of the cursor.
* @param sender Where the event comes from.
*/
- (void)deleteBackward:(id)sender - (void)deleteBackward:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_BACKSPACE, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_BACKSPACE, 0);
} }
/** Delete word left of the cursor. */ /**
* Delete word left of the cursor.
* @param sender Where the event comes from.
*/
- (void)deleteWordBackward:(id)sender - (void)deleteWordBackward:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_BACKSPACE | WKC_CTRL, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_BACKSPACE | WKC_CTRL, 0);
} }
/** Delete single character right of the cursor. */ /**
* Delete single character right of the cursor.
* @param sender Where the event comes from.
*/
- (void)deleteForward:(id)sender - (void)deleteForward:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DELETE, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DELETE, 0);
} }
/** Delete word right of the cursor. */ /**
* Delete word right of the cursor.
* @param sender Where the event comes from.
*/
- (void)deleteWordForward:(id)sender - (void)deleteWordForward:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DELETE | WKC_CTRL, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DELETE | WKC_CTRL, 0);
} }
/** Move cursor one character left. */ /**
* Move cursor one character left.
* @param sender Where the event comes from.
*/
- (void)moveLeft:(id)sender - (void)moveLeft:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_LEFT, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_LEFT, 0);
} }
/** Move cursor one word left. */ /**
* Move cursor one word left.
* @param sender Where the event comes from.
*/
- (void)moveWordLeft:(id)sender - (void)moveWordLeft:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_LEFT | WKC_CTRL, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_LEFT | WKC_CTRL, 0);
} }
/** Move cursor one character right. */ /**
* Move cursor one character right.
* @param sender Where the event comes from.
*/
- (void)moveRight:(id)sender - (void)moveRight:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_RIGHT, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_RIGHT, 0);
} }
/** Move cursor one word right. */ /**
* Move cursor one word right.
* @param sender Where the event comes from.
*/
- (void)moveWordRight:(id)sender - (void)moveWordRight:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_RIGHT | WKC_CTRL, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_RIGHT | WKC_CTRL, 0);
} }
/** Move cursor one line up. */ /**
* Move cursor one line up.
* @param sender Where the event comes from.
*/
- (void)moveUp:(id)sender - (void)moveUp:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_UP, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_UP, 0);
} }
/** Move cursor one line down. */ /**
* Move cursor one line down.
* @param sender Where the event comes from.
*/
- (void)moveDown:(id)sender - (void)moveDown:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DOWN, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DOWN, 0);
} }
/** MScroll one line up. */ /**
* MScroll one line up.
* @param sender Where the event comes from.
*/
- (void)moveUpAndModifySelection:(id)sender - (void)moveUpAndModifySelection:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_UP | WKC_SHIFT, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_UP | WKC_SHIFT, 0);
} }
/** Scroll one line down. */ /**
* Scroll one line down.
* @param sender Where the event comes from.
*/
- (void)moveDownAndModifySelection:(id)sender - (void)moveDownAndModifySelection:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DOWN | WKC_SHIFT, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_DOWN | WKC_SHIFT, 0);
} }
/** Move cursor to the start of the line. */ /**
* Move cursor to the start of the line.
* @param sender Where the event comes from.
*/
- (void)moveToBeginningOfLine:(id)sender - (void)moveToBeginningOfLine:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_HOME, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_HOME, 0);
} }
/** Move cursor to the end of the line. */ /**
* Move cursor to the end of the line.
* @param sender Where the event comes from.
*/
- (void)moveToEndOfLine:(id)sender - (void)moveToEndOfLine:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_END, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_END, 0);
} }
/** Scroll one page up. */ /**
* Scroll one page up.
* @param sender Where the event comes from.
*/
- (void)scrollPageUp:(id)sender - (void)scrollPageUp:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEUP, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEUP, 0);
} }
/** Scroll one page down. */ /**
* Scroll one page down.
* @param sender Where the event comes from.
*/
- (void)scrollPageDown:(id)sender - (void)scrollPageDown:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEDOWN, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEDOWN, 0);
} }
/** Move cursor (and selection) one page up. */ /**
* Move cursor (and selection) one page up.
* @param sender Where the event comes from.
*/
- (void)pageUpAndModifySelection:(id)sender - (void)pageUpAndModifySelection:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEUP | WKC_SHIFT, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEUP | WKC_SHIFT, 0);
} }
/** Move cursor (and selection) one page down. */ /**
* Move cursor (and selection) one page down.
* @param sender Where the event comes from.
*/
- (void)pageDownAndModifySelection:(id)sender - (void)pageDownAndModifySelection:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEDOWN | WKC_SHIFT, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_PAGEDOWN | WKC_SHIFT, 0);
} }
/** Scroll to the beginning of the document. */ /**
* Scroll to the beginning of the document.
* @param sender Where the event comes from.
*/
- (void)scrollToBeginningOfDocument:(id)sender - (void)scrollToBeginningOfDocument:(id)sender
{ {
/* For compatibility with OTTD on Win/Linux. */ /* For compatibility with OTTD on Win/Linux. */
[ self moveToBeginningOfLine:sender ]; [ self moveToBeginningOfLine:sender ];
} }
/** Scroll to the end of the document. */ /**
* Scroll to the end of the document.
* @param sender Where the event comes from.
*/
- (void)scrollToEndOfDocument:(id)sender - (void)scrollToEndOfDocument:(id)sender
{ {
/* For compatibility with OTTD on Win/Linux. */ /* For compatibility with OTTD on Win/Linux. */
[ self moveToEndOfLine:sender ]; [ self moveToEndOfLine:sender ];
} }
/** Return was pressed. */ /**
* Return was pressed.
* @param sender Where the event comes from.
*/
- (void)insertNewline:(id)sender - (void)insertNewline:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_RETURN, '\r'); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_RETURN, '\r');
} }
/** Escape was pressed. */ /**
* Escape was pressed.
* @param sender Where the event comes from.
*/
- (void)cancelOperation:(id)sender - (void)cancelOperation:(id)sender
{ {
if (EditBoxInGlobalFocus()) HandleKeypress(WKC_ESC, 0); if (EditBoxInGlobalFocus()) HandleKeypress(WKC_ESC, 0);
} }
/** Invoke the selector if we implement it. */ /**
* Invoke the selector if we implement it.
* @param aSelector The selector to invoke.
*/
- (void)doCommandBySelector:(SEL)aSelector - (void)doCommandBySelector:(SEL)aSelector
{ {
if ([ self respondsToSelector:aSelector ]) [ self performSelector:aSelector ]; if ([ self respondsToSelector:aSelector ]) [ self performSelector:aSelector ];
@@ -1237,7 +1385,10 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
} }
return self; return self;
} }
/** Handle closure requests */ /**
* Handle closure requests
* @param sender Where the event comes from.
*/
- (BOOL)windowShouldClose:(id)sender - (BOOL)windowShouldClose:(id)sender
{ {
HandleExitGameRequest(); HandleExitGameRequest();
@@ -1276,4 +1427,4 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
@end @end
#endif /* WITH_COCOA */ #endif /* WITH_COCOA or DOXYGEN_API */