Rework Mac port to be more Linux-like without needing to launch XCode. See

macos/README.txt for information.
This commit is contained in:
Mark K. Kim 2017-11-27 00:56:41 -05:00
parent 34729d4844
commit ea7f013d0d
35 changed files with 164 additions and 11762 deletions

53
custom/macos.sh Executable file
View file

@ -0,0 +1,53 @@
#!/bin/sh
BUNDLE=TuxPaint.app
BINARY="$BUNDLE/Contents/MacOS/tuxpaint"
LIBS=`find $BUNDLE/Contents/Resources/lib -type f`
TARGET="$BUNDLE/Contents/lib"
# Sanity check
if [ ! -r "$BINARY" ]; then
echo "$BINARY: Where is this file?" 1>&2
exit 1
fi
if [ ! -d "$BUNDLE" ]; then
echo "$BUNDLE: Where is this file?" 1>&2
exit 1
fi
# Ensure the shared library folder exists
mkdir -p "$TARGET"
# Copy there any shared libraries referenced by the tuxpaint binary, and any
# shared libraries those shared libraries reference, and so on. We do this by
# first copying over any shared libraries referenced by the binary, then
# repeatedly copying over the shared libraries referenced by any libraries in
# the target folder until we don't see any more files appearing. There are
# better ways to do this than copying repeatedly but it works. And you know
# what they say about premature optimization...
dylib="$BINARY $LIBS"
count=0; last=-1
echo " * Copying Shared Libraries..."
while [ $count -ne $last ]; do
cp -p `otool -L $dylib | grep '^\t[/]opt[/]local[/]' | sed -e 's/^[[:space:]]*\([^[:space:]]*\)[[:space:]].*/\1/' | sort | uniq` $TARGET
dylib="$TARGET/*"
last=$count
count=`ls -f $dylib | wc -l`
done
echo " -> Copied" $count "files to $TARGET"
# We just copied over a bunch of shared libraries into a random folder in our
# bundle, but the tuxpaint binary and the shared libraries won't know to look
# in that folder unless we tell them. So we tell them.
echo " * Fixing Shared Library References..."
for i in "$BINARY" $LIBS $TARGET/*; do
echo " -> $i..."
for j in `otool -L $dylib | grep '^\t[/]opt[/]local[/]' | sed -e 's/^[[:space:]]*\([^[:space:]]*\)[[:space:]].*/\1/'`; do
n=`echo "$j" | sed 's/^[/]opt[/]local[/]/@executable_path\/..\//'`
install_name_tool -change "$j" "$n" "$i"
done
done

View file

@ -1,33 +0,0 @@
#!/bin/bash
#//EP added in version 0.9.22
# called from within XCode
# contains customization tasks
export APP="${BUILT_PRODUCTS_DIR}/${TARGET_NAME}.app"
#export CUSTOM="${BUILT_PRODUCTS_DIR}/../../../custom/content.zip"
export CUSTOM="content.zip"
export DST="$APP/Contents/Resources"
export FONTS="$DST/fonts"
export LOG="/tmp/custom.log"
if [ -f $CUSTOM ];
then
echo Custom content file "$CUSTOM" found
echo Installing custom content into target "$APP"
echo Content folder is "$DST"
# clean up fonts folder
echo Cleaning up fonts folder "$FONTS"
/usr/bin/sudo /bin/mv -f "$FONTS/default_font.ttf" /tmp # save the font(s) we want to keep
/usr/bin/sudo /bin/rm -rf "$FONTS/"* # empty fonts folder
/usr/bin/sudo /bin/mv -f "/tmp/default_font.ttf" "$FONTS" # restore the font(s) we want to keep
# install content from archive
echo Extracting content from archive into target
/usr/bin/unzip -o "$CUSTOM" -d "$DST" > "$LOG"
echo Custom content has been installed
else
echo Custom content file $CUSTOM not found
fi

View file

@ -5,9 +5,9 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>Tux Paint</string> <string>tuxpaint</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>0.9.22, Copyright 2009, Tux Paint Development Team</string> <string>0.9.23, Copyright 2009-2017, Tux Paint Development Team</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>tuxpaint.icns</string> <string>tuxpaint.icns</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -19,14 +19,10 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.9.22</string> <string>0.9.23</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>TXPT</string> <string>TXPT</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2009-06-29</string> <string>2017-11-27</string>
<key>NSMainNibFile</key>
<string>SDLMain</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict> </dict>
</plist> </plist>

1
macos/PkgInfo Normal file
View file

@ -0,0 +1 @@
APPLTXPT

49
macos/README.txt Normal file
View file

@ -0,0 +1,49 @@
WHAT IS THIS
------------
This document describes how to build Tux Paint for macOS 10.12 Sierra and later.
Tux Paint 0.9.22 and earlier required building Tux Paint from the XCode IDE.
Starting with 0.9.23, however, Tux Paint for macOS is built as though it were a
Linux application.
REQUIREMENTS
------------
Although Tux Paint is run without the XCode IDE, XCode itself is still required
to build Tux Paint. Download it from the App Store, and launch it once to
accept its license agreements.
Building Tux Paint also requires various libraries from MacPorts. Install them
to the default /opt/local path according to the instructions found on their
website:
https://www.macports.org/
As of this writing, the required libraries are:
cairo
fribidi
libpaper
libpng
librsvg
libsdl
libsdl_image
libsdl_mixer
libsdl_pango
libsdl_ttf
zlib
... but you should intall any package that is required by the latest version of
Tux Paint.
HOW TO BUILD
------------
Simply, run:
% make
% make install
... to create the TuxPaint.app application bundle that can be run in-place or
copied to /Applications. Zip it up for distribution.

0
macosx/tuxpaint.icns → macos/tuxpaint.icns Executable file → Normal file
View file

1
macosx/.indent.pro vendored
View file

@ -1 +0,0 @@
../src/.indent.pro

View file

@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBClasses</key>
<array>
<dict>
<key>CLASS</key>
<string>TransparentTextView</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSTextView</string>
</dict>
<dict>
<key>CLASS</key>
<string>FirstResponder</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSObject</string>
</dict>
<dict>
<key>ACTIONS</key>
<dict>
<key>makeFullscreen</key>
<string>id</string>
<key>onAbout</key>
<string>id</string>
<key>onHelp</key>
<string>id</string>
<key>onNew</key>
<string>id</string>
<key>onOpen</key>
<string>id</string>
<key>onPageSetup</key>
<string>id</string>
<key>onPrint</key>
<string>id</string>
<key>onQuit</key>
<string>id</string>
<key>onRedo</key>
<string>id</string>
<key>onSave</key>
<string>id</string>
<key>onUndo</key>
<string>id</string>
</dict>
<key>CLASS</key>
<string>SDLMain</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>OUTLETS</key>
<dict>
<key>aboutWindow</key>
<string>NSWindow</string>
<key>acknowledgmentsText</key>
<string>TransparentTextView</string>
<key>appnameText</key>
<string>NSTextField</string>
<key>messagePanel</key>
<string>NSWindow</string>
<key>messageProgress</key>
<string>NSProgressIndicator</string>
<key>messageStatus</key>
<string>NSTextField</string>
<key>messageText</key>
<string>NSTextField</string>
<key>versionText</key>
<string>NSTextField</string>
</dict>
<key>SUPERCLASS</key>
<string>NSObject</string>
</dict>
</array>
<key>IBVersion</key>
<string>1</string>
</dict>
</plist>

View file

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBFramework Version</key>
<string>629</string>
<key>IBLastKnownRelativeProjectPath</key>
<string>../../TuxPaint.xcodeproj</string>
<key>IBOldestOS</key>
<integer>5</integer>
<key>IBOpenObjects</key>
<array>
<integer>372</integer>
</array>
<key>IBSystem Version</key>
<string>9C31</string>
<key>targetFramework</key>
<string>IBCocoaFramework</string>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

View file

@ -1,157 +0,0 @@
Tux Paint Xcode 2.4 Project
notes by Martin Fuhrer <mfuhrer@alumni.ucalgary.ca>
This Tux Paint project file is located in a folder titled "macosx", which should in turn be placed in the root folder of the Tux Paint source code distribution. The project will then be able to access all the source code files. You will require at least Mac OS X 10.4 and XCode 2.4 to build this project.
This XCode project has been configured under the assumption that you have certain libraries and files installed in particular locations under Mac OS X. This documentation indicates what you must install, and where these items go. Some of the libraries can be installed via the MacPorts <www.macports.org> or Fink <fink.sourceforge.net> package managers. At the time of writing, MacPorts can install one additional required library (SDL Pango) that is not available in Fink, so I have written this document with MacPorts in mind. Several libraries are either misconfigured (with regards to building Tux Paint) or unavailable in MacPorts and Fink, and need to be configured, compiled, and installed manually. You will also need to create the following "sandbox" directory where you will build and store these libraries: /Users/Shared/tuxpaint
If all this configuration and compilation sounds daunting, you may also download precompiled versions of the libraries from the Tux Paint ftp server.
-- SDL --
You must have the following frameworks installed in /Library/Frameworks:
SDL.framework
SDL_image.framework
SDL_mixer.framework
SDL_ttf.framework
You can obtain the frameworks from the SDL website <www.libsdl.org> These frameworks contain both header files and libraries, and are copied into the Frameworks directory of the Tux Paint application bundle.
-- Installing Precompiled Libraries --
Universal, pre-compiled versions of all required libraries and header files, excluding SDL, are available for download here:
ftp://ftp.tuxpaint.org/unix/x/tuxpaint/source/libs/macosx/
After unzipping the package, you will have a folder named "tuxpaint" which should be placed in /Users/Shared. You may now skip the following steps and begin building Tux Paint right away.
-- Installing Libraries via MacPorts --
The following libraries can be installed via MacPorts.
Library Install location
GNU Internationalization: /opt/local/lib/libintl.a
PNG: /opt/local/lib/libpng.a
XML Parser: /opt/local/lib/libexpat.a
Freetype: /opt/local/lib/libfreetype.a
Cairo Vector Graphics: /opt/local/lib/libcairo.a
SDL Pango: /opt/local/lib/libSDL_Pango.o
The following MacPorts command will install all these libraries in one shot:
% sudo port install libsdl_pango
Copy all the static libraries listed above into the /Users/Shared/tuxpaint/lib directory, where the XCode project will find them. By keeping the static libraries in a separate directory, we will ensure that Tux Paint will not link against other dynamic libraries in /opt/local/lib (a problematic scenario if you wish to distribute your compiled version of Tux Paint to friends who most likely don't have these dynamic libraries installed). These libraries will be statically linked into the Tux Paint binary.
-- Installing Libraries Manually --
The following libraries require manual compilation and installation.
Library Install location
XML Font Configuration: /Users/Shared/tuxpaint/lib/libfontconfig.a
GLib: /Users/Shared/tuxpaint/lib/libglib-2.0.a
/Users/Shared/tuxpaint/lib/libgobject-2.0.a
/Users/Shared/tuxpaint/lib/libgmodule-2.0.a
Pango: /Users/Shared/tuxpaint/lib/libpango-1.0.a
/Users/Shared/tuxpaint/lib/libpangoft2-1.0.a
SVG Scalable Vector Graphics: /Users/Shared/tuxpaint/lib/libsvg.a
SVG Cairo: /Users/Shared/tuxpaint/lib/libsvg-cairo.a
We will compile our libraries inside the "src" directory: /Users/Shared/tuxpaint/src
and install the libraries in the "lib" directory: /Users/Shared/tuxpaint/lib
XML Font Configuration:
This library will already have been built and installed by MacPorts, but will not have been properly configured for Tux Paint. We need to reconfigure and build Fontconfig as follows:
% cd /Users/Shared/tuxpaint/src
% cp /opt/local/var/macports/distfiles/fontconfig/fontconfig*.tar.gz .
% tar xzf fontconfig*.tar.gz
% cd fontconfig*
% sudo port deactivate fontconfig
% ./configure --prefix=/Users/Shared/tuxpaint --enable-static --disable-shared --disable-docs --with-confdir="/Library/Application Support/TuxPaint/fontconfig/fonts" --with-cache-dir="/Library/Application Support/TuxPaint/fontconfig/cache" CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
% sudo make install
% sudo port activate fontconfig
GLib:
MacPorts only installs the dynamic libraries for GLib. We need to reconfigure and build GLib with static libraries enabled as follows:
% cd /Users/Shared/tuxpaint/src
% cp /opt/local/var/macports/distfiles/glib/glib*.tar.gz .
% tar xzf glib*.tar.gz
% cd glib*
% sudo port deactivate glib2
% ./configure --prefix=/Users/Shared/tuxpaint --enable-static CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
% sudo make install
% sudo port activate glib2
Pango:
MacPorts only installs the dynamic libraries for Pango. We need to reconfigure and build Pango with static libraries enabled as follows:
% cd /Users/Shared/tuxpaint/src
% cp /opt/local/var/macports/distfiles/pango/pango*.tar.bz2 .
% tar xvjf pango*.tar
% cd pango*
% sudo port deactivate pango
% ./configure --prefix=/Users/Shared/tuxpaint --enable-static CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib --with-included-modules=yes --with-dynamic-modules=no --disable-shared
//EP pas de "make" ?
% sudo make install
% sudo find . -name "*.a" -exec cp {} /Users/Shared/tuxpaint/lib/ \;
% sudo port activate pango
SVG Scalable Vector Graphics:
Neither MacPorts nor Fink build and install the SVG library. You can retrieve sources from CVS via:
http://webcvs.cairographics.org/libsvg/
Assuming you place the sources in /Users/Shared/tuxpaint/src/libsvg, you can configure and build SVG as follows:
% cd /Users/Shared/tuxpaint/src/libsvg
% ./autogen.sh
% ./configure --prefix=/Users/Shared/tuxpaint LIBSVG_CFLAGS=-I/usr/include LIBSVG_LIBS=-L/usr/lib --disable-shared
//EP pas de "make" ?
% make install
SVG Cairo:
Neither MacPorts nor Fink build and install the SVG Cairo library. You can retrieve sources from CVS via:
http://webcvs.cairographics.org/libsvg-cairo/
Assuming you place the sources in /Users/Shared/tuxpaint/src/libsvg-cairo, you can configure and build SVG Cairo as follows:
% cd /Users/Shared/tuxpaint/src/libsvg-cairo
% ./autogen.sh
% ./configure --prefix=/Users/Shared/tuxpaint LIBSVG_CAIRO_CFLAGS=-I/Users/Shared/tuxpaint/include LIBSVG_CAIRO_LIBS=-L/Users/Shared/tuxpaint/lib --disable-shared
% make install
-- Universal and Cross Development --
Tux Paint can be built for PowerPC, Intel, or both (as a universal binary). Since Tux Paint depends on a number of libraries, these libraries must also be built for the same platform(s) for which you wish to build Tux Paint. The latest versions of the SDL frameworks are universal binary and work fine regardless what platform(s) you want to build for. On the other hand, the libraries installed via MacPorts are built only for the platform you are currently using (MacPorts offers a universal build option via the +universal variant, but this does not work for all libraries). If you want to build a universal binary of Tux Paint, you will need to manually compile these libraries as universal binaries (see http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/chapter_4_section_3.html for further information) and update the library paths (click on a library in Archives and choose File > Get Info).
To set the target platform for your build:
1) Choose Project > Edit Active Target 'Tux Paint'
2) Click the Build tab.
3) Set Configuration to "All Configurations" and Collection to "Customized Settings"
4) Select the "Architectures" setting and click the Edit button.
5) Select PowerPC, Intel, or both.
In order to allow the Tux Paint application to run on older versions of Mac OS X, it is necessary to compile and link against an older version of the Mac OS X SDK (eg. Mac OS X 10.2.8) using an older version of gcc (eg. gcc 3.3). Various versions of the Mac OS X SDKs and gcc can be installed from the XCode Installation DVD or disk image. Note that any libraries Tux Paint links against (eg. libraries installed by MacPorts) should also be compiled and linked against the same SDK, using the same version of gcc. Universal binary and Intel applications must be compiled using at least gcc 4.0 and the Mac OS X 10.4(u) SDK.
To set the desired Mac OS X SDK:
1) Choose Project > Edit Project Settings
2) Click on the General tab.
2) Choose the desired SDK from the "Cross-Develop Using Target SDK" menu.
To set the desired compiler version:
1) Choose Project > Edit Active Target 'Tux Paint'
2) Click on the Rules tab.
3) Set the desired associations between file types (eg. C++ source files) and the compiler version (eg. GCC 3.3).

View file

@ -1,48 +0,0 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
$Id$
*/
//#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_2
//#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_2
#import <Cocoa/Cocoa.h>
#import "TransparentTextView.h"
@ interface SDLMain:NSObject
{
IBOutlet NSWindow *messagePanel;
IBOutlet NSTextField *messageText;
IBOutlet NSTextField *messageStatus;
IBOutlet NSProgressIndicator *messageProgress;
IBOutlet NSWindow *aboutWindow;
IBOutlet NSTextField *appnameText;
IBOutlet NSTextField *versionText;
IBOutlet TransparentTextView *acknowledgmentsText;
}
-(IBAction) onAbout:(id) sender;
-(IBAction) onNew:(id) sender;
-(IBAction) onOpen:(id) sender;
-(IBAction) onSave:(id) sender;
-(IBAction) onPrint:(id) sender;
-(IBAction) onPageSetup:(id) sender;
-(IBAction) onUndo:(id) sender;
-(IBAction) onRedo:(id) sender;
-(IBAction) onHelp:(id) sender;
-(IBAction) onQuit:(id) sender;
-(void)sendSDLControlKeystroke:(int)key;
-(void)sendSDLControlShiftKeystroke:(int)key;
-(void)setupBridge;
-(void)displayMessage:(NSString *)
message andStatus:(NSString *)
status withProgressIndicator:(BOOL) progress;
-(void)hideMessage;
@end

View file

@ -1,744 +0,0 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import "SDL.h"
#import "SDLMain.h"
#import <sys/param.h> /* for MAXPATHLEN */
#import <unistd.h>
#include <Security/Authorization.h>
#include <Security/AuthorizationTags.h>
#include <fontconfig/fontconfig.h>
#include <stdlib.h>
#import "macosx_print.h"
#import "message.h"
#import "wrapperdata.h"
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
but the method still is there and works. To avoid warnings, we declare
it ourselves here. */
@interface NSApplication(SDL_Missing_Methods)
- (void)setAppleMenu:(NSMenu *)menu;
@end
/* Use this flag to determine whether we use SDLMain.nib or not */
#define SDL_USE_NIB_FILE 1
/* Use this flag to determine whether we use CPS (docking) or not */
#define SDL_USE_CPS 1
#ifdef SDL_USE_CPS
/* Portions of CPS.h */
typedef struct CPSProcessSerNum
{
UInt32 lo;
UInt32 hi;
} CPSProcessSerNum;
extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
#endif /* SDL_USE_CPS */
static int gArgc;
static char **gArgv;
static BOOL gFinderLaunch;
static BOOL gCalledAppMainline = FALSE;
WrapperData macosx;
SDLMain *sdlMain;
static NSString *getApplicationName(void)
{
NSDictionary *dict;
NSString *appName = 0;
/* Determine the application name */
dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey: @"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
return appName;
}
#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#endif
@interface SDLApplication : NSApplication
@end
@implementation SDLApplication
- (void)sendEvent:(NSEvent *)anEvent
{
if (!macosx.cocoaKeystrokes)
{
if (NSKeyDown == [anEvent type] || NSKeyUp == [anEvent type])
{
if( ( [anEvent modifierFlags] & NSCommandKeyMask ) == 0 )
{
return; // do not intercept keystrokes intended for SDL layer
}
}
}
[super sendEvent: anEvent];
}
/* Invoked from the Quit menu item */
- (void)terminate:(id)sender
{
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
- (void)tuxpaintHelp:(id)sender
{
NSString* helpPath = [[NSBundle mainBundle] pathForResource:@"README" ofType:@"html" inDirectory:@"html"];
[[NSWorkspace sharedWorkspace] openFile:helpPath];
}
@end
/* Class to pass information from Cocoa to SDL application */
@interface CocoaToSDLBridge : NSObject {}
- (void)dataPath:(NSString *)directory;
- (void)preferencesPath;
- (void)fontsPath;
@end
@implementation CocoaToSDLBridge
-(void) dataPath:(NSString *)directory;
{
NSBundle *mainBundle;
NSString *path;
mainBundle = [NSBundle mainBundle];
path = [mainBundle pathForResource:@"data" ofType:nil];
[path getCString:(macosx.dataPath) maxLength:sizeof(macosx.dataPath) encoding:NSUTF8StringEncoding]; //EP added maxLength: and encoding: to avoid deprecation warning for 10.6
}
-(void) preferencesPath;
{
NSString *path;
path = [@"~/Library/Application Support/TuxPaint" stringByExpandingTildeInPath];
[path getCString:(macosx.preferencesPath) maxLength:sizeof(macosx.preferencesPath) encoding:NSUTF8StringEncoding]; //EP added maxLength: and encoding: to avoid deprecation warning for 10.6
path = @"/Library/Application Support/TuxPaint";
[path getCString:(macosx.globalPreferencesPath) maxLength:sizeof(macosx.globalPreferencesPath) encoding:NSUTF8StringEncoding]; //EP added maxLength: and encoding: to avoid deprecation warning for 10.6
}
-(void) fontsPath;
{
NSString *path;
path = [@"~/Library/Fonts" stringByExpandingTildeInPath];
[path getCString:(macosx.fontsPath) maxLength:sizeof(macosx.fontsPath) encoding:NSUTF8StringEncoding]; //EP added maxLength: and encoding: to avoid deprecation warning for 10.6
}
@end
/* The main class of the application, the application's delegate */
@implementation SDLMain
- (IBAction) onAbout:(id)sender
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSDictionary *bundleInfo = [mainBundle infoDictionary];
NSMutableString *string;
NSMutableAttributedString *attributedString;
NSMutableDictionary *attributes;
/* string attributes */
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setAlignment:NSCenterTextAlignment];
attributes = [NSMutableDictionary dictionary];
[attributes setObject:[NSFont boldSystemFontOfSize:12] forKey:NSFontAttributeName];
[attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
[paragraphStyle release];
/* display Tux Paint */
string = [bundleInfo objectForKey:@"CFBundleName"];
attributedString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
[appnameText setAttributedStringValue:attributedString];
[attributedString release];
/* display version */
string = [NSMutableString stringWithString:@"Version "];
[string appendString:[bundleInfo objectForKey:@"CFBundleShortVersionString"]];
[string appendString:@" ("];
[string appendString:[bundleInfo objectForKey:@"CFBundleVersion"]];
[string appendString:@")"];
[versionText setStringValue:string];
/* display credits */
NSString *filePath = [mainBundle pathForResource:@"credits" ofType:@"txt"];
string = [NSString stringWithContentsOfFile:filePath];
[attributes setObject:[NSFont systemFontOfSize:10] forKey:NSFontAttributeName];
attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes];
[[acknowledgmentsText textStorage] setAttributedString:attributedString];
[attributedString release];
[acknowledgmentsText activateURLs];
[acknowledgmentsText setEditable:NO];
[aboutWindow makeKeyAndOrderFront:sender];
}
- (IBAction) onNew:(id)sender
{
[self sendSDLControlKeystroke:SDLK_n];
}
- (IBAction) onOpen:(id)sender
{
[self sendSDLControlKeystroke:SDLK_o];
}
- (IBAction) onSave:(id)sender
{
[self sendSDLControlKeystroke:SDLK_s];
}
- (IBAction) onPrint:(id)sender
{
macosx.menuAction = 1;
[self sendSDLControlKeystroke:SDLK_p];
macosx.menuAction = 0;
}
- (IBAction) onPageSetup:(id)sender
{
[self sendSDLControlShiftKeystroke:SDLK_p];
}
- (IBAction) onUndo:(id)sender
{
[self sendSDLControlKeystroke:SDLK_z];
}
- (IBAction) onRedo:(id)sender
{
[self sendSDLControlKeystroke:SDLK_r];
}
- (IBAction)onHelp:(id)sender
{
NSString* helpPath = [[NSBundle mainBundle] pathForResource:@"README" ofType:@"html" inDirectory:@"html"];
[[NSWorkspace sharedWorkspace] openFile:helpPath];
}
- (IBAction) onQuit:(id)sender
{
[[NSUserDefaults standardUserDefaults] synchronize];
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
- (void) sendSDLControlKeystroke:(int)key
{
SDL_Event event;
event.type = SDL_KEYDOWN;
event.key.keysym.sym = key;
event.key.keysym.mod = KMOD_CTRL;
SDL_PushEvent(&event);
}
- (void) sendSDLControlShiftKeystroke:(int)key
{
SDL_Event event;
event.type = SDL_KEYDOWN;
event.key.keysym.sym = key;
event.key.keysym.mod = KMOD_CTRL | KMOD_SHIFT;
SDL_PushEvent(&event);
}
/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
if (shouldChdir)
{
char parentdir[MAXPATHLEN];
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
}
CFRelease(url);
CFRelease(url2);
}
}
- (void) displayMessage:(NSString*)message andStatus:(NSString*)status withProgressIndicator:(BOOL)progress
{
[messageText setStringValue:message];
[messageStatus setStringValue:status];
[messagePanel makeKeyAndOrderFront:nil];
if (progress)
{
[messageProgress setUsesThreadedAnimation:YES];
[messageProgress startAnimation:nil];
}
}
- (void) hideMessage
{
[messageProgress stopAnimation:nil];
[messagePanel close];
}
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
{
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;
aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject]))
{
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
//EP commented line to avoid deprecation warning for 10.6: [aMenu sizeToFit];
}
#else
static void setApplicationMenu(void)
{
/* warning: this code is very odd */
NSMenu *appleMenu;
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
/* Tell the application object that this is now the application menu */
[NSApp setAppleMenu:appleMenu];
/* Finally give up our references to the objects */
[appleMenu release];
[menuItem release];
}
/* Create a window menu */
static void setupWindowMenu(void)
{
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
}
/* Create a window menu */
static void setupHelpMenu(void)
{
NSMenu *helpMenu;
NSMenuItem *helpMenuItem;
NSMenuItem *menuItem;
helpMenu = [[NSMenu alloc] initWithTitle:@"Help"];
/* "Help" item */
NSString *appName = getApplicationName();
menuItem = [[NSMenuItem alloc] initWithTitle:[appName stringByAppendingString:@" Help"] action:@selector(tuxpaintHelp:) keyEquivalent:@"?"];
[helpMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
helpMenuItem = [[NSMenuItem alloc] initWithTitle:@"Help" action:nil keyEquivalent:@""];
[helpMenuItem setSubmenu:helpMenu];
[[NSApp mainMenu] addItem:helpMenuItem];
/* Finally give up our references to the objects */
[helpMenu release];
[helpMenuItem release];
}
/* Replacement for NSApplicationMain */
static void CustomApplicationMain (argc, argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
/* Ensure the application object is initialised */
[SDLApplication sharedApplication];
#ifdef SDL_USE_CPS
{
CPSProcessSerNum PSN;
/* Tell the dock about us */
if (!CPSGetCurrentProcess(&PSN))
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
if (!CPSSetFrontProcess(&PSN))
[SDLApplication sharedApplication];
}
#endif /* SDL_USE_CPS */
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setApplicationMenu();
setupWindowMenu();
setupHelpMenu();
/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
/* Start the main event loop */
[NSApp run];
[sdlMain release];
[pool release];
}
#endif
/* Make Mac-specific information available to SDL app */
- (void) setupBridge
{
CocoaToSDLBridge *bridge;
bridge = [[CocoaToSDLBridge alloc] init];
[bridge autorelease];
[bridge fontsPath];
[bridge preferencesPath];
}
- (BOOL) installFontconfigFiles
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *executable = [bundle pathForAuxiliaryExecutable:@"fcinstaller"];
NSString *arguments = [NSString stringWithCString:(macosx.globalPreferencesPath)];
char command[4096];
//EP commented to avoid deprecation warning for 10.6: sprintf(command, "\"%s\" \"%s\"", [executable cString], [arguments cString]);
sprintf(command, "\"%@\" \"%@\"", executable, arguments);
int result = system(command);
return (BOOL)result;
}
- (BOOL) installFontconfigFilesWithAuthorization
{
OSStatus status;
AuthorizationFlags flags = kAuthorizationFlagDefaults;
AuthorizationRef authorizationRef;
NSBundle *bundle = [NSBundle mainBundle];
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, flags, &authorizationRef);
if (status != errAuthorizationSuccess)
return status;
AuthorizationItem items = {kAuthorizationRightExecute, 0, NULL, 0};
AuthorizationRights rights = {1, &items};
flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL);
if (status == errAuthorizationSuccess)
{
NSString *fcInstallerPath = [bundle pathForAuxiliaryExecutable:@"fcinstaller"];
char executable[2048];
char *arguments[] = { "/Library/Application Support/TuxPaint", NULL };
FILE *communicationsPipe = NULL;
strcpy(executable, [fcInstallerPath cStringUsingEncoding:NSUTF8StringEncoding]); //EP replaced cString by cStringUsingEncoding: to avoid deprecation warning for 10.6
flags = kAuthorizationFlagDefaults;
status = AuthorizationExecuteWithPrivileges(authorizationRef, executable, flags, arguments, &communicationsPipe);
}
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
return (status == errAuthorizationSuccess);
}
- (BOOL) fontconfigFilesAreInstalled
{
NSString *globalPreferencesPath = [NSString stringWithCString:(macosx.globalPreferencesPath)];
NSString *fontsPath = [globalPreferencesPath stringByAppendingString:@"/fontconfig/fonts"];
NSString *fontsConfInstalledPath = [fontsPath stringByAppendingString:@"/fonts.conf"];
NSString *fontsDtdInstalledPath = [fontsPath stringByAppendingString:@"/fonts.dtd"];
BOOL filesExist = TRUE;
NSFileManager *fileManager = [NSFileManager defaultManager];
filesExist = [fileManager fileExistsAtPath:fontsConfInstalledPath] && [fileManager fileExistsAtPath:fontsDtdInstalledPath];
return filesExist;
}
/* Set up Fontconfig */
- (void) setupFontconfig
{
/* Tell Fontconfig to use font configuration file in application bundle */
setenv ("FONTCONFIG_PATH", [[[NSBundle mainBundle] resourcePath] cStringUsingEncoding:NSUTF8StringEncoding], 1); //EP replaced cString by cStringUsingEncoding: to avoid deprecation warning for 10.6
/* Install font configuration file */
/*
BOOL filesExist = [self fontconfigFilesAreInstalled];
if (!filesExist)
{
[self installFontconfigFiles];
filesExist = [self fontconfigFilesAreInstalled];
if (!filesExist)
{
[self installFontconfigFilesWithAuthorization];
filesExist = [self fontconfigFilesAreInstalled];
if (!filesExist)
exit(-1);
}
}
*/
/* Determine if Fontconfig cache needs to be built */
NSString *globalPreferencesPath = [NSString stringWithCString:(macosx.globalPreferencesPath)];
NSString *globalCachePath = [globalPreferencesPath stringByAppendingString:@"/fontconfig/cache"];
NSString *userCachePath = [[NSString stringWithString:@"~/.fontconfig"] stringByExpandingTildeInPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:globalCachePath] && ![fileManager fileExistsAtPath:userCachePath])
{
/* Build Fontconfig cache */
displayMessage( MSG_FONT_CACHE );
FcBool initSuccess = FcInit();
hideMessage();
}
}
/*
* Catch document open requests...this lets us notice files when the app
* was launched by double-clicking a document, or when a document was
* dragged/dropped on the app's icon. You need to have a
* CFBundleDocumentsType section in your Info.plist to get this message,
* apparently.
*
* Files are added to gArgv, so to the app, they'll look like command line
* arguments. Previously, apps launched from the finder had nothing but
* an argv[0].
*
* This message may be received multiple times to open several docs on launch.
*
* This message is ignored once the app's mainline has been called.
*/
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
const char *temparg;
size_t arglen;
char *arg;
char **newargv;
if (!gFinderLaunch) /* MacOS is passing command line args. */
return FALSE;
if (gCalledAppMainline) /* app has started, ignore this document. */
return FALSE;
temparg = [filename UTF8String];
arglen = SDL_strlen(temparg) + 1;
arg = (char *) SDL_malloc(arglen);
if (arg == NULL)
return FALSE;
newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
if (newargv == NULL)
{
SDL_free(arg);
return FALSE;
}
gArgv = newargv;
SDL_strlcpy(arg, temparg, arglen);
gArgv[gArgc++] = arg;
gArgv[gArgc] = NULL;
return TRUE;
}
- (BOOL)textView:(NSTextView*)textView clickedOnLink:(id)link atIndex:(unsigned)charIndex
{
BOOL success;
success = [[NSWorkspace sharedWorkspace] openURL: link];
return success;
}
/* Called when the internal event loop has just started running */
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
int status;
sdlMain = self;
/* Allow Cocoa events to be processed */
setenv ("SDL_ENABLEAPPEVENTS", "1", 1);
/* Set up Cocoa to SDL bridge */
[self setupBridge];
/* Set up Fontconfig */
[self setupFontconfig];
/* Set the working directory to the .app's parent directory */
[self setupWorkingDirectory:gFinderLaunch];
#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif
/* Hand off to main application code */
gCalledAppMainline = TRUE;
status = SDL_main (gArgc, gArgv);
/* We're done, thank you for playing */
exit(status);
}
@end
@implementation NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
{
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;
bufferSize = selfLen + aStringLen - aRange.length;
buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
/* Get first part into buffer */
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];
/* Get middle part into buffer */
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer+aRange.location) range:localRange];
/* Get last part into buffer */
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
/* Build output string */
result = [NSString stringWithCharacters:buffer length:bufferSize];
NSDeallocateMemoryPages(buffer, bufferSize);
return result;
}
@end
#ifdef main
# undef main
#endif
/* Main entry point to executable - should *not* be SDL_main! */
int main (int argc, char **argv)
{
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
gArgv[0] = argv[0];
gArgv[1] = NULL;
gArgc = 1;
gFinderLaunch = YES;
} else {
int i;
gArgc = argc;
gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
for (i = 0; i <= argc; i++)
gArgv[i] = argv[i];
gFinderLaunch = NO;
}
#if SDL_USE_NIB_FILE
[SDLApplication poseAsClass:[NSApplication class]];
NSApplicationMain (argc, (const char**) argv);
#else
CustomApplicationMain (argc, argv);
#endif
return 0;
}

View file

@ -1,32 +0,0 @@
//
// TransparentTextView.h
// Tux Paint
//
// Created by Martin Fuhrer on Wed Dec 12 2007.
// Copyright (c) 2007 Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#import <Cocoa/Cocoa.h>
@interface TransparentTextView : NSTextView
{
}
- (void)activateURLs;
@end

View file

@ -1,92 +0,0 @@
//
// TransparentTextView.m
// Tux Paint
//
// Created by Martin Fuhrer on Wed Dec 12 2007.
// Copyright (c) 2007 Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#import "TransparentTextView.h"
@implementation TransparentTextView
- (void)drawViewBackgroundInRect:(NSRect)rect
{
}
- (BOOL)isOpaque
{
return NO;
}
- (void)activateURLs
{
NSTextStorage* textStorage = [self textStorage];
NSString* string = [textStorage string];
NSRange searchRange = NSMakeRange(0, [string length]);
NSRange foundRange;
[textStorage beginEditing];
do
{
// assume that all URLs are enclosed between < >
foundRange = [string rangeOfString:@"<" options:0 range:searchRange];
if (foundRange.length > 0) //Did we find a URL?
{
NSURL* theURL;
NSMutableString* theURLString;
NSDictionary* linkAttributes;
NSRange endOfURLRange, range;
// restrict the searchRange so that it won't find the same string again
searchRange.location = foundRange.location + foundRange.length;
searchRange.length = [string length] - searchRange.location;
// assume the URL ends with >
endOfURLRange = [string rangeOfString:@">" options:0 range:searchRange];
// set foundRange's length to the length of the URL
foundRange.location++;
foundRange.length = endOfURLRange.location - foundRange.location;
// grab the URL from the text and format it properly
range = [[string substringWithRange:foundRange] rangeOfString:@"@"];
if (range.length > 0)
theURLString = [NSMutableString stringWithString:@"mailto:"];
else
theURLString = [NSMutableString stringWithString:@"http://"];
[theURLString appendString:[string substringWithRange:foundRange]];
// generate URL
theURL = [NSURL URLWithString:theURLString];
// make the link attributes
linkAttributes = [NSDictionary dictionaryWithObjectsAndKeys: theURL, NSLinkAttributeName,
[NSColor blueColor], NSForegroundColorAttributeName, nil];
// apply those attributes to the URL in the text
[textStorage addAttributes:linkAttributes range:foundRange];
}
}
while (foundRange.length != 0); //repeat the do block until it no longer finds anything
[textStorage endEditing];
}
@end

File diff suppressed because it is too large Load diff

View file

@ -1,11 +0,0 @@
(c) 2009 Tux Paint Development Team
Website:
<www.tuxpaint.org>
Mac OS X build:
Martin Fuhrer <mfuhrer@gmail.com>
Universal binary made possible with assistance from:
Carlo Gandolfi <www.freesmug.org>
Douglas Barbieri

View file

@ -1,109 +0,0 @@
//
// fcinstaller.m
// TuxPaint
//
// Created by Martin Fuhrer on 03/02/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#import <Foundation/Foundation.h>
#include <fontconfig/fontconfig.h>
/* Category for NSFileManager */
@interface NSFileManager (CreateDirectoryRecursively)
- (BOOL)createDirectoryRecursively:(NSString *)path attributes:(NSDictionary *)attributes;
@end
int main(int argc, const char* argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSBundle *bundle = [NSBundle mainBundle];
NSString *bundlePath = [bundle bundlePath];
BOOL success = TRUE;
BOOL fileExists = TRUE;
if( argc < 2 )
return -1;
NSString *globalPreferencesPath = [NSString stringWithCString:(argv[1])];
NSString *fontsPath = [globalPreferencesPath stringByAppendingString:@"/fontconfig/fonts"];
NSString *fontsConfInstalledPath = [fontsPath stringByAppendingString:@"/fonts.conf"];
NSString *fontsDtdInstalledPath = [fontsPath stringByAppendingString:@"/fonts.dtd"];
NSString *fontsConfBundlePath = [bundle pathForResource:@"fonts" ofType:@"conf"];
NSString *fontsDtdBundlePath = [bundle pathForResource:@"fonts" ofType:@"dtd"];
fileExists = [fileManager fileExistsAtPath:fontsConfInstalledPath];
if (!fileExists) {
success = ([fileManager createDirectoryRecursively:fontsPath attributes:nil] && success);
success = ([fileManager copyPath:fontsConfBundlePath toPath:fontsConfInstalledPath handler:nil] && success);
}
fileExists = [fileManager fileExistsAtPath:fontsDtdInstalledPath];
if (!fileExists) {
success = ([fileManager createDirectoryRecursively:fontsPath attributes:nil] && success);
success = ([fileManager copyPath:fontsDtdBundlePath toPath:fontsDtdInstalledPath handler:nil] && success);
}
/*
NSString *globalCachePath = [globalPreferencesPath stringByAppendingString:@"/fontconfig/cache"];
NSString *userCachePath = [[NSString stringWithString:@"~/.fontconfig"] stringByExpandingTildeInPath];
fileExists = ([fileManager fileExistsAtPath:globalCachePath] || [fileManager fileExistsAtPath:userCachePath]);
if (!fileExists)
{
FcBool initSuccess = FcInit();
if( initSuccess == FcFalse )
success = FALSE;
}
*/
[pool release];
return (int)(!success);
}
@implementation NSFileManager (CreateDirectoryRecursively)
- (BOOL)createDirectoryRecursively:(NSString *)path attributes:(NSDictionary *)attributes
{
BOOL isDir = TRUE;
BOOL fileExists;
fileExists = [self fileExistsAtPath:path isDirectory:&isDir];
if (isDir) {
if (fileExists) {
/* directory exists */
return TRUE;
}
else
{
/* create directory */
NSString *parentDirectory = [path stringByDeletingLastPathComponent];
[self createDirectoryRecursively:parentDirectory attributes:attributes];
return [self createDirectoryAtPath:path attributes:attributes];
}
}
else
{
/* desired directory path is blocked by a file */
return FALSE;
}
}
@end

View file

@ -1,458 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts.conf file to configure system font access -->
<fontconfig>
<!--
The intent of this standard configuration file is to be adequate for
most environments. If you have a reasonably normal environment and
have found problems with this configuration, they are probably
things that others will also want fixed. Please send any suggested
changes to fonts@xfree86.org so that future releases can include
such changes.
Note that the normal 'make install' procedure for XFree86 is to
replace any existing fonts.conf file with the new version. Place
any local customizations in local.conf which this file references.
Keith Packard
-->
<!-- Font directory list configured on Sun Sep 14 17:12:54 PDT 2003 -->
<!--
//EP
//commented out paths that prevented Inuktitut from rendering
-->
<dir>/Library/Fonts</dir>
<dir>/Network/Library/Fonts</dir>
<!--dir>/System/Library/Fonts</dir-->
<dir>/usr/X11R6/lib/X11/fonts/Type1</dir>
<dir>/usr/X11R6/lib/X11/fonts/TTF</dir>
<dir>/usr/share/fonts</dir>
<dir>~/Library/Fonts</dir>
<dir>~/.fonts</dir>
<!--
//EP
//<cache> was ignored and every program init was slow
//replaced it by <cachedir> which reenabled the cache font and sped up further program inits
<cache>~/.fontconfig</cache>
-->
<cachedir>~/.fontconfig</cachedir>
<!--
Enable sub-pixel rendering
<match target="font">
<test qual="all" name="rgba">
<const>unknown</const>
</test>
<edit name="rgba" mode="assign"><const>rgb</const></edit>
</match>
-->
<!--
Accept deprecated 'mono' alias, replacing it with 'monospace'
-->
<match target="pattern">
<test qual="any" name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign">
<string>monospace</string>
</edit>
</match>
<!--
Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans serif</string>
</test>
<edit name="family" mode="assign">
<string>sans-serif</string>
</edit>
</match>
<!--
Accept deprecated 'sans' alias, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign">
<string>sans-serif</string>
</edit>
</match>
<!--
Mark common families with their generics so we'll get
something reasonable
-->
<!--
Serif faces
-->
<!--
//EP
//this generated Fontconfig warning: line XXX: Having multiple <family> in <alias> isn't supported and may not work as expected
//fixed by splitting alias so as to get only one family per alias
<alias>
<family>Times</family>
<family>Times New Roman</family>
<family>Nimbus Roman No9 L</family>
<family>Luxi Serif</family>
<family>Kochi Mincho</family>
<family>AR PL SungtiL GB</family>
<family>AR PL Mingti2L Big5</family>
<family>Baekmuk Batang</family>
<default><family>serif</family></default>
</alias>
-->
<alias>
<family>Times</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Times New Roman</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Nimbus Roman No9 L</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Luxi Serif</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Kochi Mincho</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>AR PL SungtiL GB</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>AR PL Mingti2L Big5</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Baekmuk Batang</family>
<default><family>serif</family></default>
</alias>
<!--
Sans-serif faces
-->
<!--
//EP
//this generated Fontconfig warning: line XXX: Having multiple <family> in <alias> isn't supported and may not work as expected
//fixed by splitting alias so as to get only one family per alias
<alias>
<family>Lucida Grande</family>
<family>Geneva</family>
<family>Helvetica</family>
<family>Arial</family>
<family>Verdana</family>
<family>Nimbus Sans L</family>
<family>Luxi Sans</family>
<family>Osaka</family>
<family>Kochi Gothic</family>
<family>AR PL KaitiM GB</family>
<family>AR PL KaitiM Big5</family>
<family>Baekmuk Dotum</family>
<family>SimSun</family>
<default><family>sans-serif</family></default>
</alias>
-->
<alias>
<family>Lucida Grande</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Geneva</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Helvetica</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Arial</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Verdana</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Nimbus Sans L</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Luxi Sans</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Osaka</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Kochi Gothic</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>AR PL KaitiM GB</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>AR PL KaitiM Big5</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Baekmuk Dotum</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>SimSun</family>
<default><family>sans-serif</family></default>
</alias>
<!--
Monospace faces
-->
<!--
//EP
//this generated Fontconfig warning: line XXX: Having multiple <family> in <alias> isn't supported and may not work as expected
//fixed by splitting alias so as to get only one family per alias
<alias>
<family>Monaco</family>
<family>Courier</family>
<family>Courier New</family>
<family>Andale Mono</family>
<family>Luxi Mono</family>
<family>Nimbus Mono L</family>
<family>NSimSun</family>
<default><family>monospace</family></default>
</alias>
-->
<alias>
<family>Monaco</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Courier</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Courier New</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Andale Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Luxi Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Nimbus Mono L</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>NSimSun</family>
<default><family>monospace</family></default>
</alias>
<!--
If the font still has no generic name, add sans-serif
-->
<match target="pattern">
<test qual="all" name="family" compare="not_eq">
<string>sans-serif</string>
</test>
<test qual="all" name="family" compare="not_eq">
<string>serif</string>
</test>
<test qual="all" name="family" compare="not_eq">
<string>monospace</string>
</test>
<edit name="family" mode="append_last">
<string>sans-serif</string>
</edit>
</match>
<!--
Load per-user customization file
-->
<include ignore_missing="yes">~/.fonts.conf</include>
<!--
Load local system customization file
-->
<include ignore_missing="yes">local.conf</include>
<!--
Alias well known font names to available TrueType fonts
-->
<alias>
<family>Times</family>
<accept><family>Times New Roman</family></accept>
</alias>
<alias>
<family>Helvetica</family>
<accept><family>Verdana</family></accept>
</alias>
<alias>
<family>Arial</family>
<accept><family>Verdana</family></accept>
</alias>
<alias>
<family>Courier</family>
<accept><family>Courier New</family></accept>
</alias>
<!--
Provide required aliases for standard names
-->
<alias>
<family>serif</family>
<prefer>
<family>Times New Roman</family>
<family>Nimbus Roman No9 L</family>
<family>Luxi Serif</family>
<family>Times</family>
<family>Kochi Mincho</family>
<family>AR PL SungtiL GB</family>
<family>AR PL Mingti2L Big5</family>
<family>Baekmuk Batang</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Lucida Grande</family>
<family>Geneva</family>
<family>Verdana</family>
<family>Nimbus Sans L</family>
<family>Luxi Sans</family>
<family>Arial</family>
<family>Helvetica</family>
<family>Kochi Gothic</family>
<family>Osaka</family>
<family>AR PL KaitiM GB</family>
<family>AR PL KaitiM Big5</family>
<family>Baekmuk Dotum</family>
<family>SimSun</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Monaco</family>
<family>Andale Mono</family>
<family>Courier New</family>
<family>Luxi Mono</family>
<family>Nimbus Mono L</family>
<family>Kochi Gothic</family>
<family>AR PL KaitiM GB</family>
<family>Baekmuk Dotum</family>
</prefer>
</alias>
<!--
Artificial oblique for fonts without an italic or oblique version
-->
<match target="font">
<!-- check to see if the font is roman -->
<test name="slant">
<const>roman</const>
</test>
<!-- check to see if the pattern requested non-roman -->
<test target="pattern" name="slant" compare="not_eq">
<const>roman</const>
</test>
<!-- multiply the matrix to slant the font -->
<edit name="matrix" mode="assign">
<times>
<name>matrix</name>
<matrix><double>1</double><double>.2</double>
<double>0</double><double>1</double>
</matrix>
</times>
</edit>
<!-- pretend the font is oblique now -->
<edit name="slant" mode="assign">
<const>oblique</const>
</edit>
</match>
<config>
<!--
These are the default Unicode chars that are expected to be blank
in fonts. All other blank chars are assumed to be broken and
won't appear in the resulting charsets
-->
<blank>
<int>0x0020</int> <!-- SPACE -->
<int>0x00a0</int> <!-- NO-BREAK SPACE -->
<int>0x00ad</int> <!-- SOFT HYPHEN -->
<int>0x115f</int> <!-- HANGUL CHOSEONG FILLER -->
<int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
<int>0x1680</int> <!-- OGHAM SPACE MARK -->
<int>0x2000</int> <!-- EN QUAD -->
<int>0x2001</int> <!-- EM QUAD -->
<int>0x2002</int> <!-- EN SPACE -->
<int>0x2003</int> <!-- EM SPACE -->
<int>0x2004</int> <!-- THREE-PER-EM SPACE -->
<int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
<int>0x2006</int> <!-- SIX-PER-EM SPACE -->
<int>0x2007</int> <!-- FIGURE SPACE -->
<int>0x2008</int> <!-- PUNCTUATION SPACE -->
<int>0x2009</int> <!-- THIN SPACE -->
<int>0x200a</int> <!-- HAIR SPACE -->
<int>0x200b</int> <!-- ZERO WIDTH SPACE -->
<int>0x200c</int> <!-- ZERO WIDTH NON-JOINER -->
<int>0x200d</int> <!-- ZERO WIDTH JOINER -->
<int>0x200e</int> <!-- LEFT-TO-RIGHT MARK -->
<int>0x200f</int> <!-- RIGHT-TO-LEFT MARK -->
<int>0x2028</int> <!-- LINE SEPARATOR -->
<int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
<int>0x202a</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
<int>0x202b</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
<int>0x202c</int> <!-- POP DIRECTIONAL FORMATTING -->
<int>0x202d</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
<int>0x202e</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
<int>0x202f</int> <!-- NARROW NO-BREAK SPACE -->
<int>0x205f</int> <!-- MEDIUM MATHEMATICAL SPACE -->
<int>0x2060</int> <!-- WORD JOINER -->
<int>0x2061</int> <!-- FUNCTION APPLICATION -->
<int>0x2062</int> <!-- INVISIBLE TIMES -->
<int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
<int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
<int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
<int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
<int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
<int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
<int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
<int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
<int>0x3164</int> <!-- HANGUL FILLER -->
<int>0xfeff</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
<int>0xffa0</int> <!-- HALFWIDTH HANGUL FILLER -->
<int>0xfff9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
<int>0xfffa</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
<int>0xfffa</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
</blank>
<!--
Rescan configuration every 30 seconds when FcFontSetList is called
-->
<rescan>
<int>30</int>
</rescan>
</config>
</fontconfig>

View file

@ -1,222 +0,0 @@
<!-- This is the Document Type Definition for font configuration files -->
<!ELEMENT fontconfig (dir |
cache |
cachedir |
include |
config |
selectfont |
match |
alias)* >
<!--
Add a directory that provides fonts
-->
<!ELEMENT dir (#PCDATA)>
<!ATTLIST dir xml:space (default|preserve) 'preserve'>
<!--
Define the per-user file that holds cache font information.
If the filename begins with '~', it is replaced with the users
home directory path.
-->
<!ELEMENT cache (#PCDATA)>
<!ATTLIST cache xml:space (default|preserve) 'preserve'>
<!--
Add a directory that is searched for font cache files.
These hold per-directory cache data and are searched in
order for each directory. When writing cache files, the first
directory which allows the cache file to be created is used.
A leading '~' in a directory name is replaced with the users
home directory path.
-->
<!ELEMENT cachedir (#PCDATA)>
<!ATTLIST cachedir xml:space (default|preserve) 'preserve'>
<!--
Reference another configuration file; note that this
is another complete font configuration file and not
just a file included by the XML parser.
Set 'ignore_missing' to 'yes' if errors are to be ignored.
If the filename begins with '~', it is replaced with the users
home directory path.
-->
<!ELEMENT include (#PCDATA)>
<!ATTLIST include
ignore_missing (no|yes) "no"
xml:space (default|preserve) "preserve">
<!--
Global library configuration data
-->
<!ELEMENT config (blank|rescan)*>
<!--
Specify the set of Unicode encoding values which
represent glyphs that are allowed to contain no
data. With this list, fontconfig can examine
fonts for broken glyphs and eliminate them from
the set of valid Unicode chars. This idea
was borrowed from Mozilla
-->
<!ELEMENT blank (int)*>
<!--
Aliases are just a special case for multiple match elements
They are syntactically equivalent to:
<match>
<test name="family">
<string value=[family]/>
</test>
<edit name="family" mode="prepend">
<string value=[prefer]/>
...
</edit>
<edit name="family" mode="append">
<string value=[accept]/>
...
</edit>
<edit name="family" mode="append_last">
<string value=[default]/>
...
</edit>
</match>
-->
<!--
Periodically rescan the font configuration and
directories to synch internal state with filesystem
-->
<!ELEMENT rescan (int)>
<!--
Edit list of available fonts at startup/reload time
-->
<!ELEMENT selectfont (rejectfont | acceptfont)* >
<!ELEMENT rejectfont (glob | pattern)*>
<!ELEMENT acceptfont (glob | pattern)*>
<!ELEMENT glob (#PCDATA)>
<!ELEMENT pattern (patelt)*>
<!ENTITY % constant 'int|double|string|matrix|bool|charset|const'>
<!ELEMENT patelt (%constant;)*>
<!ATTLIST patelt
name CDATA #REQUIRED>
<!ELEMENT alias (family*, prefer?, accept?, default?)>
<!ELEMENT prefer (family)*>
<!ELEMENT accept (family)*>
<!ELEMENT default (family)*>
<!ELEMENT family (#PCDATA)>
<!ATTLIST family xml:space (default|preserve) 'preserve'>
<!ENTITY % expr 'int|double|string|matrix|bool|charset
|name|const
|or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
|plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
<!--
Match and edit patterns.
If 'target' is 'pattern', execute the match before selecting a font.
if 'target' is 'font', execute the match on the result of a font
selection.
-->
<!ELEMENT match (test*, edit*)>
<!ATTLIST match
target (pattern|font|scan) "pattern">
<!--
Match a field in a pattern
if 'qual' is 'any', then the match succeeds if any value in the field matches.
if 'qual' is 'all', then the match succeeds only if all values match.
if 'qual' is 'first', then the match succeeds only if the first value matches.
if 'qual' is 'not_first', then the match succeeds only if any value other than
the first matches.
For match elements with target=font, if test 'target' is 'pattern',
then the test is applied to the pattern used in matching rather than
to the resulting font.
Match elements with target=scan are applied as fonts are scanned.
They edit the pattern generated from the scanned font and affect
what the fontconfig database contains.
-->
<!ELEMENT test (%expr;)*>
<!ATTLIST test
qual (any|all|first|not_first) "any"
name CDATA #REQUIRED
target (pattern|font|default) "default"
compare (eq|not_eq|less|less_eq|more|more_eq|contains|not_contains) "eq">
<!--
Edit a field in a pattern
The enclosed values are used together to edit the list of values
associated with 'name'.
If 'name' matches one of those used in a test element for this match element:
if 'mode' is 'assign', replace the matched value.
if 'mode' is 'assign_replace', replace all of the values
if 'mode' is 'prepend', insert before the matched value
if 'mode' is 'append', insert after the matched value
if 'mode' is 'prepend_first', insert before all of the values
if 'mode' is 'append_last', insert after all of the values
If 'name' doesn't match any of those used in a test element:
if 'mode' is 'assign' or 'assign_replace, replace all of the values
if 'mode' is 'prepend' or 'prepend_first', insert before all of the values
if 'mode' is 'append' or 'append_last', insert after all of the values
-->
<!ELEMENT edit (%expr;)*>
<!ATTLIST edit
name CDATA #REQUIRED
mode (assign|assign_replace|prepend|append|prepend_first|append_last) "assign"
binding (weak|strong|same) "weak">
<!--
Elements of expressions follow
-->
<!ELEMENT int (#PCDATA)>
<!ATTLIST int xml:space (default|preserve) 'preserve'>
<!ELEMENT double (#PCDATA)>
<!ATTLIST double xml:space (default|preserve) 'preserve'>
<!ELEMENT string (#PCDATA)>
<!ATTLIST string xml:space (default|preserve) 'preserve'>
<!ELEMENT matrix (double,double,double,double)>
<!ELEMENT bool (#PCDATA)>
<!ELEMENT charset (#PCDATA)>
<!ATTLIST charset xml:space (default|preserve) 'preserve'>
<!ELEMENT name (#PCDATA)>
<!ATTLIST name xml:space (default|preserve) 'preserve'>
<!ELEMENT const (#PCDATA)>
<!ATTLIST const xml:space (default|preserve) 'preserve'>
<!ELEMENT or (%expr;)*>
<!ELEMENT and (%expr;)*>
<!ELEMENT eq ((%expr;), (%expr;))>
<!ELEMENT not_eq ((%expr;), (%expr;))>
<!ELEMENT less ((%expr;), (%expr;))>
<!ELEMENT less_eq ((%expr;), (%expr;))>
<!ELEMENT more ((%expr;), (%expr;))>
<!ELEMENT more_eq ((%expr;), (%expr;))>
<!ELEMENT contains ((%expr;), (%expr;))>
<!ELEMENT not_contains ((%expr;), (%expr;))>
<!ELEMENT plus (%expr;)*>
<!ELEMENT minus (%expr;)*>
<!ELEMENT times (%expr;)*>
<!ELEMENT divide (%expr;)*>
<!ELEMENT not (%expr;)>
<!ELEMENT if ((%expr;), (%expr;), (%expr;))>
<!ELEMENT floor (%expr;)>
<!ELEMENT ceil (%expr;)>
<!ELEMENT round (%expr;)>
<!ELEMENT trunc (%expr;)>

View file

@ -1,27 +0,0 @@
//
// message.h
// Tux Paint
//
// Created by Martin Fuhrer on Sat Dec 8 2007.
// Copyright (c) 2007 Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#define MSG_FONT_CACHE 1
void displayMessage(int msgId);
void hideMessage();

View file

@ -1,55 +0,0 @@
//
// message.m
// Tux Paint
//
// Created by Martin Fuhrer on Sat Dec 8 2007.
// Copyright (c) 2007 Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#import "SDLMain.h"
#import "message.h"
extern SDLMain* sdlMain;
void displayMessage( int msgId )
{
NSString *message = nil;
NSString *status = nil;
if( sdlMain == nil )
return;
switch( msgId )
{
case( MSG_FONT_CACHE ):
message = @"I'm currently fishing for fonts on your Mac. This may take me a minute, as I'd much rather be feeding on fish from the sea.";
status = @"Status: Caching fonts (this only needs to be done once)...";
[sdlMain displayMessage:message andStatus:status withProgressIndicator:YES];
break;
default:
break;
}
}
void hideMessage()
{
if( sdlMain == nil )
return;
[sdlMain hideMessage];
}

View file

@ -1,14 +0,0 @@
#Test en changeant les chemins orginaux des bibliotheques dynamiques
#sudo mv /usr/local/lib /usr/local/_lib
#sudo mv /opt/local/lib /opt/local/_lib
sudo mv /Library/Frameworks/SDL.framework /Library/Frameworks/_SDL.framework
sudo mv /Library/Frameworks/SDL_image.framework /Library/Frameworks/_SDL_image.framework
sudo mv /Library/Frameworks/SDL_mixer.framework /Library/Frameworks/_SDL_mixer.framework
sudo mv /Library/Frameworks/SDL_ttf.framework /Library/Frameworks/_SDL_ttf.framework
"$1"
sudo mv /Library/Frameworks/_SDL.framework /Library/Frameworks/SDL.framework
sudo mv /Library/Frameworks/_SDL_image.framework /Library/Frameworks/SDL_image.framework
sudo mv /Library/Frameworks/_SDL_mixer.framework /Library/Frameworks/SDL_mixer.framework
sudo mv /Library/Frameworks/_SDL_ttf.framework /Library/Frameworks/SDL_ttf.framework
#sudo mv /opt/local/_lib /opt/local/lib
#sudo mv /usr/local/_lib /usr/local/lib

View file

@ -1,365 +0,0 @@
/*
* patch.c
* TuxPaint
*
* Created by Eric (EP) on 13-09-13.
* Copyright 2013 __MyCompanyName__. All rights reserved.
*
* Patch to fix code (incompatible, missing...) //EP
*
*/
#include <stdlib.h>
#include <errno.h>
#include <mm_malloc.h>
#include <png.h>
#include "patch.h"
// missing from wchar.h on Mac
wchar_t *wcsdup(const wchar_t * ws)
{
wchar_t *ret;
size_t len;
len = wcslen(ws);
ret = malloc((len + 1) * sizeof(wchar_t));
if (ret == 0)
return ret;
return (wcscpy(ret, ws));
}
// missing, needed by __nl_find_msg in libintl.a(dcigettext.o)
// http://forums.macrumors.com/showthread.php?t=1284479
#undef iconv_t
typedef void *iconv_t;
extern size_t libiconv(iconv_t cd, char * *inbuf, size_t * inbytesleft, char * *outbuf, size_t * outbytesleft);
extern iconv_t libiconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft)
{
return libiconv(cd, inbuf, inbytesleft, outbuf, outbytesleft);
}
iconv_t iconv_open(const char *tocode, const char *fromcode)
{
return libiconv_open(tocode, fromcode);
}
// to fix ineffective setlocale() in i18n.c or force language to Inuktitut
// must be called prior to setup_i18n()
patch_i18n(const char *locale)
{
setenv("LANG", locale, 1); // takes language passed as an argument
// setenv("LANG", "iu_CA.UTF-8", 1); // forces language to Inuktitut
}
#ifdef PATCH_10_5
// missing, needed by __udivmodti4
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/int_lib.h
#include <limits.h>
typedef unsigned su_int;
typedef long long di_int;
typedef unsigned long long du_int;
#ifdef __i386__
typedef int ti_int __attribute__ ((mode(DI)));
typedef unsigned tu_int __attribute__ ((mode(DI)));
#else
typedef int ti_int __attribute__ ((mode(TI)));
typedef unsigned tu_int __attribute__ ((mode(TI)));
#endif
typedef union
{
tu_int all;
struct
{
#if _YUGA_LITTLE_ENDIAN
du_int low;
du_int high;
#else
du_int high;
du_int low;
#endif /* _YUGA_LITTLE_ENDIAN */
} s;
} utwords;
// missing, needed by __umodti3 and __udivti3
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/udivmodti4.c
tu_int __udivmodti4(tu_int a, tu_int b, tu_int * rem)
{
const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
utwords n;
n.all = a;
utwords d;
d.all = b;
utwords q;
utwords r;
unsigned sr;
/* special cases, X is unknown, K != 0 */
if (n.s.high == 0)
{
if (d.s.high == 0)
{
/* 0 X
* ---
* 0 X
*/
if (rem)
*rem = n.s.low % d.s.low;
return n.s.low / d.s.low;
}
/* 0 X
* ---
* K X
*/
if (rem)
*rem = n.s.low;
return 0;
}
/* n.s.high != 0 */
if (d.s.low == 0)
{
if (d.s.high == 0)
{
/* K X
* ---
* 0 0
*/
if (rem)
*rem = n.s.high % d.s.low;
return n.s.high / d.s.low;
}
/* d.s.high != 0 */
if (n.s.low == 0)
{
/* K 0
* ---
* K 0
*/
if (rem)
{
r.s.high = n.s.high % d.s.high;
r.s.low = 0;
*rem = r.all;
}
return n.s.high / d.s.high;
}
/* K K
* ---
* K 0
*/
if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
{
if (rem)
{
r.s.low = n.s.low;
r.s.high = n.s.high & (d.s.high - 1);
*rem = r.all;
}
return n.s.high >> __builtin_ctzll(d.s.high);
}
/* K K
* ---
* K 0
*/
sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
/* 0 <= sr <= n_udword_bits - 2 or sr large */
if (sr > n_udword_bits - 2)
{
if (rem)
*rem = n.all;
return 0;
}
++sr;
/* 1 <= sr <= n_udword_bits - 1 */
/* q.all = n.all << (n_utword_bits - sr); */
q.s.low = 0;
q.s.high = n.s.low << (n_udword_bits - sr);
/* r.all = n.all >> sr; */
r.s.high = n.s.high >> sr;
r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
}
else /* d.s.low != 0 */
{
if (d.s.high == 0)
{
/* K X
* ---
* 0 K
*/
if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
{
if (rem)
*rem = n.s.low & (d.s.low - 1);
if (d.s.low == 1)
return n.all;
unsigned sr = __builtin_ctzll(d.s.low);
q.s.high = n.s.high >> sr;
q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
return q.all;
}
/* K X
* ---
* 0 K
*/
sr = 1 + n_udword_bits + __builtin_clzll(d.s.low) - __builtin_clzll(n.s.high);
/* 2 <= sr <= n_utword_bits - 1
* q.all = n.all << (n_utword_bits - sr);
* r.all = n.all >> sr;
* if (sr == n_udword_bits)
* {
* q.s.low = 0;
* q.s.high = n.s.low;
* r.s.high = 0;
* r.s.low = n.s.high;
* }
* else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
* {
* q.s.low = 0;
* q.s.high = n.s.low << (n_udword_bits - sr);
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
* {
* q.s.low = n.s.low << (n_utword_bits - sr);
* q.s.high = (n.s.high << (n_utword_bits - sr)) |
* (n.s.low >> (sr - n_udword_bits));
* r.s.high = 0;
* r.s.low = n.s.high >> (sr - n_udword_bits);
* }
*/
q.s.low = (n.s.low << (n_utword_bits - sr)) & ((di_int) (int)(n_udword_bits - sr) >> (n_udword_bits - 1));
q.s.high = ((n.s.low << (n_udword_bits - sr)) &
((di_int) (int)(sr - n_udword_bits - 1) >> (n_udword_bits - 1))) |
(((n.s.high << (n_utword_bits - sr)) |
(n.s.low >> (sr - n_udword_bits))) & ((di_int) (int)(n_udword_bits - sr) >> (n_udword_bits - 1)));
r.s.high = (n.s.high >> sr) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1));
r.s.low = ((n.s.high >> (sr - n_udword_bits)) &
((di_int) (int)(n_udword_bits - sr - 1) >> (n_udword_bits - 1))) |
(((n.s.high << (n_udword_bits - sr)) |
(n.s.low >> sr)) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1)));
}
else
{
/* K X
* ---
* K K
*/
sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
/*0 <= sr <= n_udword_bits - 1 or sr large */
if (sr > n_udword_bits - 1)
{
if (rem)
*rem = n.all;
return 0;
}
++sr;
/* 1 <= sr <= n_udword_bits */
/* q.all = n.all << (n_utword_bits - sr); */
q.s.low = 0;
q.s.high = n.s.low << (n_udword_bits - sr);
/* r.all = n.all >> sr;
* if (sr < n_udword_bits)
* {
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else
* {
* r.s.high = 0;
* r.s.low = n.s.high;
* }
*/
r.s.high = (n.s.high >> sr) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1));
r.s.low = (n.s.high << (n_udword_bits - sr)) |
((n.s.low >> sr) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1)));
}
}
/* Not a special case
* q and r are initialized with:
* q.all = n.all << (n_utword_bits - sr);
* r.all = n.all >> sr;
* 1 <= sr <= n_utword_bits - 1
*/
su_int carry = 0;
for (; sr > 0; --sr)
{
/* r:q = ((r:q) << 1) | carry */
r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1));
r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1));
q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1));
q.s.low = (q.s.low << 1) | carry;
/* carry = 0;
* if (r.all >= d.all)
* {
* r.all -= d.all;
* carry = 1;
* }
*/
const ti_int s = (ti_int) (d.all - r.all - 1) >> (n_utword_bits - 1);
carry = s & 1;
r.all -= d.all & s;
}
q.all = (q.all << 1) | carry;
if (rem)
*rem = r.all;
return q.all;
}
// missing, needed by __cairo_uint128_divrem in libcairo.a(cairo-wideint.o)
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/umodti3.c
tu_int __umodti3(tu_int a, tu_int b)
{
tu_int r;
__udivmodti4(a, b, &r);
return r;
}
// missing, needed by __cairo_uint128_divrem in libcairo.a(cairo-wideint.o)
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/udivti3.c
tu_int __udivti3(tu_int a, tu_int b)
{
return __udivmodti4(a, b, 0);
}
// missing, needed by __nl_log_untranslated in libintl.a(log.o) for 10.5
FILE *fopen$DARWIN_EXTSN(const char *filename, const char *mode)
{
return fopen(filename, mode);
}
// missing, needed by _slab_allocator_alloc_chunk in libglib-2.0.a(libglib_2_0_la-gslice.o) for 10.5
// http://www.spinics.net/lists/fio/msg00700.html
// http://www.publicsource.apple.com/source/clang/clang-137/src/tools/clang/lib/Headers/mm_malloc.h
int posix_memalign(void **ptr, size_t align, size_t size)
{
if (ptr)
{
*ptr = _mm_malloc(size, align);
return 0;
}
return ENOMEM;
}
#endif // PATCH_10_5
#ifdef PATCH_LIBPNG_EARLIER_THAN_1_5
// missing in libpng<1.5, needed by _Load_SBit_Png in libfreetype.a(sfnt.o), _error_callback in libfreetype.a(sfnt.o)
// http://stackoverflow.com/questions/5190554/unresolved-external-png-set-longjmp-fn-in-libpng
// http://cpansearch.perl.org/src/JTPALMER/Alien-SDL-1.439_1/patches/SDL_image-1.2.10-libpng15.patch
typedef jmp_buf *(*png_set_longjmp_fnPtr) (png_structp, void *, size_t);
png_set_longjmp_fnPtr png_set_longjmp_fn = 0;
#endif

View file

@ -1,14 +0,0 @@
/*
* patch.h
* TuxPaint
*
* Created by Eric on 13-09-13.
* Copyright 2013 __MyCompanyName__. All rights reserved.
*
* Patch to fix code (incompatible, missing...) //EP
*
*/
#include <wchar.h>
wchar_t *wcsdup(const wchar_t *);

View file

@ -1,24 +0,0 @@
//
// speech.h
// TuxPaint
//
// Created by Martin Fuhrer on 13/12/07.
// Copyright (c) 2007 Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
void speak_string(const wchar_t * str);

View file

@ -1,53 +0,0 @@
//
// speech.m
// TuxPaint
//
// Created by Martin Fuhrer on 13/12/07.
// Copyright (c) 2007 Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#import <Cocoa/Cocoa.h>
#import "speech.h"
#import "i18n.h"
void speak_string(const wchar_t *widecharString)
{
#ifndef __APPLE_10_2_8__
char multibyteString[1024];
NSString *string = [NSString string];
// speech synthesizer can pronounce only English phonemes and syllables
int lang = get_current_language();
if( lang != LANG_EN && lang != LANG_EN_GB && lang != LANG_EN_ZA )
return;
NSArray *voices = [NSSpeechSynthesizer availableVoices];
NSSpeechSynthesizer *synthesizer = [[NSSpeechSynthesizer alloc] init];
wcstombs(multibyteString,widecharString,sizeof(multibyteString));
if( [string respondsToSelector:@selector(string:stringWithCString:encoding:)] )
string = [NSString stringWithCString:multibyteString encoding:NSUTF8StringEncoding];
else
string = [NSString stringWithCString:multibyteString];
// speak string using a random voice
[synthesizer setVoice:[voices objectAtIndex:rand()%[voices count]]];
[synthesizer startSpeakingString:string];
[synthesizer release];
#endif // !__APPLE_10_2_8__
}

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>92</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>ProductBuildVersion</key>
<string>7K571</string>
<key>ProjectName</key>
<string>NibPBTemplates</string>
<key>SourceVersion</key>
<string>1200000</string>
</dict>
</plist>

View file

@ -1,30 +0,0 @@
/*
* wrapperdata.h
* Tux Paint
*
* Created by Martin Fuhrer on Wed May 12 2004.
* Copyright (c) 2004 __MyCompanyName__. All rights reserved.
*
* $Id$
*
*/
#ifndef WRAPPER_DATA
#define WRAPPER_DATA
struct WrapperDataStruct
{
char dataPath[2048]; // path to data folder inside Tux Paint application bundle
char preferencesPath[2048]; // path to the user's Tux Paint preferences folder
char globalPreferencesPath[2048]; // path to all users' Tux Paint preferences folder
char fontsPath[2048]; // path to the user's fonts folder
int foundSDL; // was SDL.framework found?
int foundSDL_image; // was SDL_image.framework found?
int foundSDL_mixer; // was SDL_mixer.framework found?
int cocoaKeystrokes; // should keystrokes be intercepted by Cocoa wrapper?
int menuAction; // was the action initiated by a Mac OS X menu selection?
};
typedef struct WrapperDataStruct WrapperData;
#endif

48
src/macos.c Normal file
View file

@ -0,0 +1,48 @@
#include <stdlib.h>
#include "macos.h"
#define MACOS_FONTS_PATH "%s/Library/Fonts"
#define MACOS_PREFERENCES_PATH "%s/Library/Application Support/TuxPaint"
#define MACOS_GLOBAL_PREFERENCES_PATH "/Library/Application Support/TuxPaint"
const char* macos_fontsPath()
{
static char* p = NULL;
if(!p) {
const char* home = getenv("HOME");
p = malloc(strlen(home) + strlen(MACOS_FONTS_PATH) + 1);
if(p) sprintf(p, MACOS_FONTS_PATH, getenv("HOME"));
else perror("macos_fontsPath");
}
return p;
}
const char* macos_preferencesPath()
{
static char* p = NULL;
if(!p) {
const char* home = getenv("HOME");
p = malloc(strlen(home) + strlen(MACOS_PREFERENCES_PATH) + 1);
if(p) sprintf(p, MACOS_PREFERENCES_PATH, getenv("HOME"));
else perror("macos_preferencesPath");
}
return p;
}
const char* macos_globalPreferencesPath()
{
return MACOS_GLOBAL_PREFERENCES_PATH;
}

9
src/macos.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef __MACOS_H__
#define __MACOS_H__
const char* macos_fontsPath();
const char* macos_preferencesPath();
const char* macos_globalPreferencesPath();
#endif /* __MACOS_H__ */

View file

@ -1,40 +0,0 @@
//
// macosx_print.h
// Tux Paint
//
// Created by Darrell Walisser on Sat Mar 15 2003.
// Modified by Martin Fuhrer 2007.
// Copyright (c) 2007 Darrell Walisser, Martin Fuhrer. All rights reserved.
// $Id$
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
#include "SDL.h"
const char *SurfacePrint(SDL_Surface * surface, int showDialog);
int DisplayPageSetup(const SDL_Surface * surface);
#ifdef OBJECTIVEC
@interface PrintSheetController:NSObject
{
bool displayPrintSetupSheet;
bool displayPrintSheet;
}
-@end
#endif /* OBJECTIVEC */

View file

@ -1,327 +0,0 @@
//
// macosx_print.m
// Tux Paint
//
// Created by Darrell Walisser on Sat Mar 15 2003.
// Modified by Martin Fuhrer 2007.
// Copyright (c) 2007 Darrell Walisser, Martin Fuhrer.
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// (See COPYING.txt)
//
// $Id$
//
#import "macosx_print.h"
#import "wrapperdata.h"
#import <Cocoa/Cocoa.h>
extern WrapperData macosx;
NSData* printData = nil;
// this object presents the image to the printing layer
@interface ImageView : NSView
{
NSImage* _image;
}
- (void) setImage:(NSImage*)image;
@end
@implementation ImageView
- (void) setImage:(NSImage*)image
{
_image = [ image retain ];
}
- (void) drawRect:(NSRect)rect
{
[ _image compositeToPoint: NSMakePoint( 0, 0 ) operation: NSCompositeCopy ];
}
- (BOOL) scalesWhenResized
{
return YES;
}
@end
// this object waits for the print dialog to go away
@interface ModalDelegate : NSObject
{
BOOL _complete;
BOOL _wasOK;
}
- (id) init;
- (BOOL) wait;
- (void) reset;
- (BOOL) wasOK;
@end
@implementation ModalDelegate
- (id) init
{
self = [ super init ];
_complete = NO;
_wasOK = NO;
return self;
}
- (BOOL) wait
{
while (!_complete) {
NSEvent *event;
event = [ NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[ NSDate distantFuture ]
inMode: NSDefaultRunLoopMode dequeue:YES ];
[ NSApp sendEvent:event ];
}
return [ self wasOK ];
}
- (void) reset
{
_complete = NO;
_wasOK = NO;
}
- (BOOL) wasOK
{
return _wasOK;
}
- (void)printDidRun:(NSPrintOperation *)printOperation
success:(BOOL)success contextInfo:(void *)contextInfo
{
_complete = YES;
_wasOK = success;
}
- (void)pageLayoutEnded:(NSPageLayout *)pageLayout
returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
_complete = YES;
_wasOK = returnCode == NSOKButton;
}
@end
static NSImage* CreateImage( SDL_Surface *surface )
{
NSBitmapImageRep* imageRep;
NSSize imageSize;
NSImage* image;
SDL_Surface* surface32RGBA;
// convert surface to 32bit RGBA
#ifdef BIG_ENDIAN_ARCH
surface32RGBA = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h,
32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0 );
#else
surface32RGBA = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h,
32, 0xff<<0, 0xff<<8, 0xff<<16, 0xff<<24 );
#endif
if( surface32RGBA == NULL ) {
NSLog (@"CreateImage: Cannot allocate conversion surface");
return nil;
}
SDL_BlitSurface( surface, NULL, surface32RGBA, NULL );
// convert surface to an NSBitmapImageRep
imageRep = [ [ NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&surface32RGBA->pixels
pixelsWide:surface->w
pixelsHigh:surface->h
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:surface->w * 4
bitsPerPixel:32 ];
if( imageRep == nil ) {
NSLog (@"CreateImage: Could not create image representation.");
return nil;
}
imageSize = NSMakeSize( surface->w, surface->h );
image = [ [ NSImage alloc ] initWithSize:imageSize ];
if( image == nil ) {
NSLog (@"CreateImage: Could not allocate image");
return nil;
}
[ image addRepresentation:imageRep ];
[ image setScalesWhenResized:YES ];
[ image setDataRetained:YES ];
[ image autorelease ];
[ imageRep release ];
free( surface32RGBA );
return image;
}
void DefaultPrintSettings( const SDL_Surface *surface, NSPrintInfo *printInfo )
{
if( surface->w > surface->h )
[ printInfo setOrientation:NSLandscapeOrientation ];
else
[ printInfo setOrientation:NSPortraitOrientation ];
[ printInfo setHorizontallyCentered:true ];
[ printInfo setVerticallyCentered:true ];
[ printInfo setVerticalPagination:NSFitPagination ];
[ printInfo setHorizontalPagination:NSFitPagination ];
}
NSPrintInfo* LoadPrintInfo( const SDL_Surface *surface )
{
NSUserDefaults* standardUserDefaults;
NSPrintInfo* printInfo;
NSData* printData = nil;
static BOOL firstTime = YES;
standardUserDefaults = [ NSUserDefaults standardUserDefaults ];
if( standardUserDefaults )
printData = [ standardUserDefaults dataForKey:@"PrintInfo" ];
if( printData )
printInfo = (NSPrintInfo*)[ NSUnarchiver unarchiveObjectWithData:printData ];
else
{
printInfo = [ NSPrintInfo sharedPrintInfo ];
if( firstTime == YES )
{
DefaultPrintSettings( surface, printInfo );
firstTime = NO;
}
}
return printInfo;
}
void SavePrintInfo( NSPrintInfo* printInfo )
{
NSUserDefaults* standardUserDefaults;
NSData* printData = nil;
printData = [ NSArchiver archivedDataWithRootObject:printInfo ];
standardUserDefaults = [ NSUserDefaults standardUserDefaults ];
if( standardUserDefaults )
[ standardUserDefaults setObject:printData forKey:@"PrintInfo" ];
}
int DisplayPageSetup( const SDL_Surface * surface )
{
NSPageLayout* pageLayout;
NSPrintInfo* printInfo;
ModalDelegate* delegate;
BOOL result;
macosx.cocoaKeystrokes = 1;
printInfo = LoadPrintInfo( surface );
delegate = [ [ [ ModalDelegate alloc ] init ] autorelease ];
pageLayout = [ NSPageLayout pageLayout ];
[ pageLayout beginSheetWithPrintInfo:printInfo
modalForWindow:[ NSApp mainWindow ]
delegate:delegate
didEndSelector:@selector(pageLayoutEnded:returnCode:contextInfo:)
contextInfo:nil ];
result = [ delegate wait ];
SavePrintInfo( printInfo );
macosx.cocoaKeystrokes = 0;
return (int)( result );
}
const char* SurfacePrint( SDL_Surface *surface, int showDialog )
{
NSImage* image;
ImageView* printView;
NSWindow* printWindow;
NSPrintOperation* printOperation;
NSPrintInfo* printInfo;
ModalDelegate* delegate;
BOOL ok = YES;
// check if printers are available
NSArray* printerNames = [NSPrinter printerNames];
if( [printerNames count] == 0 && !showDialog)
return "No printer is available. Run Tux Paint in window mode (not fullscreen), and select File > Print... to choose a printer.";
// create image for surface
image = CreateImage( surface );
if( image == nil )
return "Could not create a print image.";
// create print control objects
printInfo = LoadPrintInfo( surface );
NSRect pageRect = [ printInfo imageablePageBounds ];
NSSize pageSize = pageRect.size;
NSPoint pageOrigin = pageRect.origin;
[ printInfo setTopMargin:pageOrigin.y ];
[ printInfo setLeftMargin:pageOrigin.x ];
[ printInfo setRightMargin:pageOrigin.x ];
[ printInfo setBottomMargin:pageOrigin.y ];
float surfaceRatio = (float)( surface->w ) / (float)( surface->h );
float pageRatio = pageSize.width / pageSize.height;
NSSize imageSize = pageSize;
if( pageRatio > surfaceRatio ) // wide page
imageSize.width = surface->w * pageSize.height / surface->h;
else // tall page
imageSize.height = surface->h * pageSize.width / surface->w;
// create print view
printView = [ [ [ ImageView alloc ] initWithFrame: NSMakeRect( 0, 0, imageSize.width, imageSize.height ) ] autorelease ];
if (printView == nil)
return "Could not create a print view.";
[ image setSize:imageSize ];
[ printView setImage:image ];
// run printing
printOperation = [ NSPrintOperation printOperationWithView:printView printInfo:printInfo ];
[ printOperation setShowsPrintPanel:showDialog ]; //EP replaced setShowPanels by setShowsPrintPanel
macosx.cocoaKeystrokes = 1;
delegate = [ [ [ ModalDelegate alloc ] init ] autorelease ];
[ printOperation runOperationModalForWindow:[ NSApp mainWindow ]
delegate:delegate didRunSelector:@selector(printDidRun:success:contextInfo:) contextInfo:nil ];
ok = [ delegate wait ];
macosx.cocoaKeystrokes = 0;
SavePrintInfo( printInfo );
[ image release ];
return NULL;
}