The Battle for Wesnoth  1.19.0-dev
SDLMain.mm
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2024
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /* SDLMain.m - main entry point for our Cocoa-ized SDL app
16  Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
17  Non-NIB-Code & other changes: Max Horn <max@quendi.de>
18  Edited a lot for Wesnoth by Ben Anderman <ben@happyspork.com>
19 */
20 
21 #import "SDL.h"
22 #import "SDLMain.h"
23 #include <vector>
24 
25 #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
26 #define NSEventTypeKeyDown NSKeyDown
27 #define NSEventTypeKeyUp NSKeyUp
28 #define NSEventModifierFlagCommand NSCommandKeyMask
29 #endif
30 
31 extern "C" int wesnoth_main(int argc, char **argv);
32 static std::vector<char*> gArgs;
33 
34 @interface WesnothSDLApplication : NSApplication
35 @end
36 
37 @implementation WesnothSDLApplication
38 /* Invoked from the Quit menu item */
39 - (void)terminate:(id)sender
40 {
41  (void) sender;
42  /* Post a SDL_QUIT event */
43  SDL_Event event;
44  event.type = SDL_QUIT;
45  SDL_PushEvent(&event);
46 }
47 
48 - (BOOL)_handleKeyEquivalent:(NSEvent *)theEvent
49 {
50  [[super mainMenu] performKeyEquivalent:theEvent];
51  return YES;
52 }
53 
54 - (void) sendEvent:(NSEvent *)event
55 {
56  if(NSEventTypeKeyDown == [event type] || NSEventTypeKeyUp == [event type])
57  {
58  if([event modifierFlags] & NSEventModifierFlagCommand)
59  {
60  [super sendEvent: event];
61  }
62  } else {
63  [super sendEvent: event];
64  }
65 }
66 @end
67 
68 /* The main class of the application, the application's delegate */
69 @implementation SDLMain
70 
71 - (IBAction) openHomepage:(id)sender
72 {
73  (void) sender;
74  [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.wesnoth.org/"]];
75 }
76 
77 - (IBAction) openChangelog:(id)sender
78 {
79  (void) sender;
80  NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
81  NSString* url = [NSString stringWithFormat:@"https://changelog.wesnoth.org/%@", version];
82  [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
83 }
84 
85 /* Called when the internal event loop has just started running */
86 - (void) applicationDidFinishLaunching: (NSNotification *) note
87 {
88  (void) note;
89  /* This makes SDL give events to Cocoa, so it can handle things like command+h to hide, etc. */
90  setenv ("SDL_ENABLEAPPEVENTS", "1", 1);
91  setenv ("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
92 
93  /* Set config files for pango and fontconfig, so the data they need can be found */
94  setenv ("PANGO_RC_FILE", "./pangorc", 1);
95  setenv ("PANGO_SYSCONFDIR", ".", 1);
96  setenv ("PANGO_LIBDIR", ".", 1);
97  setenv ("FONTCONFIG_PATH", "./fonts/", 1);
98  setenv ("FONTCONFIG_FILE", "fonts.conf", 1);
99 
100  int status;
101 
102  /* Set the working directory to the .app's Resources directory */
103  chdir([[[NSBundle mainBundle] resourcePath] fileSystemRepresentation]);
104 
105  /* Hand off to main application code */
106  status = wesnoth_main(gArgs.size() - 1, gArgs.data());
107 
108  /* We're done, thank you for playing */
109  exit(status);
110 }
111 @end
112 
113 template<int sz>
114 bool str_eq(const char* str, const char(& cstr)[sz]) {
115  return strncmp(str, cstr, sz) == 0;
116 }
117 
118 #ifdef main
119 # undef main
120 #endif
121 
122 /* Main entry point to executable - should *not* be SDL_main! */
123 int main (int argc, char **argv)
124 {
125  gArgs.push_back(argv[0]); // Program name
126  for (int i = 1; i < argc; i++) {
127  // Filter out debug arguments that XCode might pass
128  if (str_eq(argv[i], "-ApplePersistenceIgnoreState")) {
129  i++; // Skip the argument
130  continue;
131  }
132  if (str_eq(argv[i], "-NSDocumentRevisionsDebugMode")) {
133  i++; // Skip the argument
134  continue;
135  }
136  // This is passed if launched by double-clicking
137  if (strncmp(argv[i], "-psn", 4) == 0) {
138  continue;
139  }
140  gArgs.push_back(argv[i]);
141  }
142  gArgs.push_back(nullptr);
143 
144  [WesnothSDLApplication sharedApplication];
145 
146  [[NSBundle mainBundle] loadNibNamed:@"SDLMain" owner:NSApp topLevelObjects:nil];
147 
148  [NSApp run];
149  return 0;
150 }
bool str_eq(const char *str, const char(&cstr)[sz])
Definition: SDLMain.mm:114
#define NSEventTypeKeyUp
Definition: SDLMain.mm:27
#define NSEventModifierFlagCommand
Definition: SDLMain.mm:28
int main(int argc, char **argv)
Definition: SDLMain.mm:123
#define NSEventTypeKeyDown
Definition: SDLMain.mm:26
int wesnoth_main(int argc, char **argv)
static std::vector< char * > gArgs
Definition: SDLMain.mm:32
std::size_t i
Definition: function.cpp:968